Performance problem

Performance problem

Old forum URL: forums.lhotka.net/forums/t/1710.aspx


crepinv posted on Tuesday, November 07, 2006

Hello all.
 
I have a problem that I hope someone has ever encountered in the past because it is a major issue for us. The problem is simple. Because we deploy all our applications in a load-balanced environment, the http session is configured to use SQL Server. For some of our applications, we've found a major performance issue due to this fact. Some objects (BusinessBase) are quite large and take a enormous time to serialize themselves (when the session goes to the database, the objects are serialized as you know).
 
Here are some details and numbers:
 
For one of the applications that has a problem, the model is quite simple.Essentially, there is an Application object having Functionalities (composition) each having Access and AccesProfil children. The problem occurs when I edit an Application object (which has about 100 Fonctionnalites each having about 5-10 Acces and AccesProfilage children).For me these numbers are far from extreme. The result is that the serialized Application object weighs about 5 megabytes !!! and the time to serialize it using the simple:
 
  ''' <summary>
    ''' Creates a serialized representation of the object.
    ''' </summary>
    ''' <returns>A byte representation of the object.</returns>
    Protected Function GetObjectAsByte(ByVal bOject As Object) As Byte()
 
        Dim buffer As New MemoryStream
        Dim formatter As New BinaryFormatter
        formatter.Serialize(buffer, bOject)
        buffer.Close()
        Return buffer.ToArray()
 
    End Function
 
takes more than 30 seconds on my laptop (very recent HP with 2G of memory).
 
Do you have any idea of what could be wrong ?
 
Thank you very much.
 
Vincent Crepin

ajj3085 replied on Wednesday, November 08, 2006

Well, this is a web app.  Rocky recommends (for the reasons you indicate) that pretty much all objects in your design must be root objects.  That is, they can be fetched and saved independant of each other.  It sounds like this is not how you designed your BOs, and the best solution is likely to make the children into root objects as well.  That way you're only storing one object at a time.

Search around the forum for Csla and Asp.net.  That should give more detailed discussions on this topic.

davidb replied on Wednesday, November 08, 2006

Hi Vincent,

Are you using the CSLA undo feature in you web app? Calling the BeginEdit method directly or through the IEditableObject interface can greatly increase the size of the object graph that need to be serialized. As you may already know, the undo feature causes the children collections to be serialized into the root object internal undo stack.

Maybe this causes the size of your object graph to grow and thus slows down the serialization process.

I hope this help. Good luck,

David

tetranz replied on Wednesday, November 08, 2006

Hi Vincent

You code doesn't indicate this but I wonder if your child objects have a reference to their parent?  If they do then you must mark it with the NotUndoable() and (I think) NonSerializable() attributes. If you do not do that and you do a BeginEdit() then the BeginEdit() will go into a loop. The loop usually stops eventually (I'm not sure why) but your serialized objects are very large.

Cheers
Ross

JoeFallon1 replied on Thursday, November 09, 2006

For what it is worth,

I use ASP.Net State Server service and it has the same performance hit for large objects.

I try to keep the stuff in State to a minimum but sometimes I need the whole BO. When I leave the page I make sure to clear out any unused objects from Session to keep it is small as possible. (i.e. the ones that were used on the page I just left.)

Also - this idea of re-designing your BOs as all root objects is not a path I ever went down - nor will I. The whole point of these BOs is to be able to re-use them in various environments. Not have to re-design them for a web app. Things work fine when the BOs are designed the standard way.

Joe

 

pelinville replied on Thursday, November 09, 2006

JoeFallon1:

For what it is worth,

I use ASP.Net State Server service and it has the same performance hit for large objects.

I try to keep the stuff in State to a minimum but sometimes I need the whole BO. When I leave the page I make sure to clear out any unused objects from Session to keep it is small as possible. (i.e. the ones that were used on the page I just left.)

Also - this idea of re-designing your BOs as all root objects is not a path I ever went down - nor will I. The whole point of these BOs is to be able to re-use them in various environments. Not have to re-design them for a web app. Things work fine when the BOs are designed the standard way.

Joe

You can reuse the "all root" BOs just as well as the "standard" ones.  You just have to be a little more careful with the design.

shawndewet replied on Thursday, November 09, 2006

Hi Vincent, here's my tuppence:

I had a serious performance problem when binding child collections to a root object, and wanting to update the parent object's IsDirty to True whenever an object in the child collection changed.  I would add an event handler in my root object to the child collections' IsDirtyChanged event.  This event handler would then call the root object's MarkDirty.  I had major performance problems when dealing with a child object in this scenario.  Well after much head scratching and using VS2005 Team Developer Performance Tools, it turned out that this event handling was the problem.  Well I still wanted my root object to report itself as dirty if any of the child collection objects were dirty.  So I changed the approach by overriding the IsDirty property of the root object so that it reports a short-circuited combination of MyBase.IsDirty and also MyChildCollection(1..n).IsDirty.  That was the end of those performace problems.  Hope it helps with your scenario, or anyone else reading this thread? 

davidb replied on Monday, November 27, 2006

Since your problem is related to the serialization of the object graph I tought you might be interested in this article: http://www.codeproject.com/dotnet/FastSerializer.asp.

In this two part article the author explains how to replace the standard .NET serialization process by a custom implementation that provides roughly 10 times speed imporvement and reduction of the size of the serialized data.

If this solution proves to be useful and brings better performances, maybe it could be included in some way in the CSLA framework or in a Contrib project.

davidb 

crepinv replied on Wednesday, December 13, 2006

Hello again. Thank you very much for all the answers. I've been through many investigations and fixes. I can now pretend that everything works "blazingly" fast. The problems were multiple. A little of all everybody posted. First, we were using beginEdit which was indeed increasing the size of the serialized objects substantially. It was not necessary to keep the undo state when navigating away from the page so I "cancelEdited" before serializing the state. Second and mostly, I implemented a small pattern which consists into releasing the child collections before navigating away from the page. A sort of active lazy load pattern. This way, when I create or edit a child object, I ask the parent to return it as Detached and I release the child collections before leaving the page to go to the child page. When I come back, the child collection gets re-fetched (lazy load) and I reattach the newly created or edited object. Using these 2 simple strategies, I could reduce the size of my serialized state from many megabytes to a maximum of 20k!!!

By the way, the business rules are always enforced on the parent object by contrast of the "all root objects" strategy which I prefer.

A little disadvantage of this strategy is that I cannot release a child collection that is dirty but that never happens in my web scenario.

Vincent.

ajj3085 replied on Wednesday, December 13, 2006

Vincent,

Glad you were able to figure things out.  Just as a note, N-level undo really isn't meant to be used in web apps at all, for many of the reasons you encountered.  Check out the book for more info.

Andy

crepinv replied on Wednesday, December 13, 2006

Yes I know. It was used to allow a journalization mechanism with old values and new values.
 
Vincent.
----- Original Message -----
From: ajj3085
To: vincent.crepin@elapsetech.com
Sent: Wednesday, December 13, 2006 3:59 PM
Subject: Re: [CSLA .NET] Performance problem

Vincent,

Glad you were able to figure things out.  Just as a note, N-level undo really isn't meant to be used in web apps at all, for many of the reasons you encountered.  Check out the book for more info.

Andy



crepinv replied on Wednesday, December 13, 2006

Yes I know. We were using it for a journalization mechanism that provides old values and new values. But it was not necessary to keep that state when leaving the page.

Vincent.

Copyright (c) Marimer LLC