How to Improve Performance of CSLA for Silverlight

CSLA for Silverlight is using MobileFormatter class to serialize and de-0serialize the data that if sent across the wire during client/server communications.  General flow of the serialization process is as follows.  Each object that implements IMobileObject is being asked by mobile formatter to serialize its data into a list of SerializationInfo objects.  That list maintains the state of each object as well as the relationships between objects.  Ultimately, the data consist of simple properties serialized into FieldData objects and relationships between objects into ChildData objects.  The formatter then is using DataContactSerializer and XML Reader/Writer combination in order to create byte arrays from object data.  These byte arrays are just XML blobs when all said and done of SerializationInfo objects.  DataContractSerializer is doing the best job it can in order to specify enough information in the XML to make it possible to reconstruct the data on the other end of the wire.  As a result, it drops hints from XML standards that specify what primate type should be used for each property value of each objects.  This results in extremely verbose XML, where each property may take additional 20-30 bytes to specify the type to be used.  On top of that, CSLA is using descriptive names inside Serialization Info object as well as generic dictionaries to store ChildData and FIeldData objects.  Turns out, serializer puts enough metadata around generic collections as well that makes them larger.

So, we took a few steps to provide some optimization around the code that should work with any version of CSLA that has MobileFormatter.  First of all, we changed DataMember and DataContract attributes to provider shorter names.  For example, instead of Value property we will just have VU in the XML.  We also created helper dictionaries instead of using generic dictionaries in order to be able to specify names for items and keys, all consisting of 2 letter instead of 4-10 letter.  Also, we eliminated XML type hints by injecting a xmlns namespace into XML header containing the root namespace of XML standards with one letter alias, which will eliminate 20-30 bytes from each serialized property.

Your particular results may vary, but we saw overall improvements of 2-50 percent depending on the objects.  Since Mobile Formatter is also used to take snapshots of objects to support Cancel button (undo) functionality, you will also see memory improvements in your Silverlight application as well.

Please read the warning message at the end of the article before you decide to use this code.

You can download attached SerializationInfo and make changes to your version of CSLA.  You will also need to find the following method in MobileFormatter

public void Serialize(XmlWriter writer, object graph)

 

and replace it with the code below:

    public void Serialize(XmlWriter writer, object graph)

    {

      List<SerializationInfo> serialized = SerializeAsDTO(graph);

 

      DataContractSerializer dc = GetDataContractSerializer();

 

      dc.WriteStartObject(writer, serialized);

      writer.WriteAttributeString("xmlns", "z", null, "http://www.w3.org/2001/XMLSchema");

      dc.WriteObjectContent(writer, serialized);

      dc.WriteEndObject(writer);

    }

 

WARNING – the byte arrays are not going to be compatible with previous CSLA version.  So, if you are serializing objects using MobileFormatter and storing them somewhere, you will not be able to de-serialize them after you make the change.

You can also download SerializationInfo file here.

 

8 Comments

  1. Why use the DataContract serializer at all? If you’re only serializing 3 classes (SerializationInfo, FieldInfo, and ClassInfo), why not write a hand-coded serializer for each? We did this (see http://forums.lhotka.net/forums/p/10726/50057.aspx#50057 source code link included) and we’ve seen about a 5x improvement in memory usage during serialization, and about a 4x improvement in the size of the serialized data. In addition we are routinely serializing large data sets (>10k objects) in less than 5 sec. We’ve had this code in production for about a month, without a single issue.

  2. @tbaldridge
    I talked to Rocky about your post, and we are going to be using similar approach, but I am not sure yet if it is going to be 100% the same. Your formatter handles a lot of types (IDS enumeration), but not all. We will need to make sure all types are handled. I think we have a good plan, I just have not had the time yet to get all the coding completed.
    Thanks for your help and input.
    Sergey

  3. Yeah, that is one of the downsides of my approach. There are some types that aren’t supported at all. And so we’ve been forced to make a few modifications to it (for instance, handling GUIDs and longs). On the other hand, it’s nice to be able to have “native” support for some types not supported by the contract serializer (for instance, Dictionary isn’t supported last I checked). It’d be nice to be able to extend the default serializer to be able to treat almost any type as a “value” type.

    I’m excited to see where these improvements go.

    Timothy

  4. This is great news as this will offer improvements to numerous projects we have.

    Sergey, can you confirm that the eventual changes to CSLA 4.3 will actually be different (and better) than the suggested changes attached to this blog post.

    I guess what I’m asking is, if the changes from 4.3 will be different to these, then I’d rather wait for that.

    Thanks for the hard work!
    Jaans

  5. The changes in 4.3 are totally different, and impprove performance a lot more. In my tests I saw that load drops in half in comparison with what I posted above. As a matter of fact, those changes are already checked in, and you could get them by getting the latest in SVN.

  6. Do you have a performance benchmark comparing CSLA vs. WCF Service vs. WCF RIA Service?

    Sending data from IIS to Silverlight client, and sending data from Silverlight client to IIS.

    CPU and memory usages.

    Benchmark over DSL, Cable internet connection.

    CSLA cannot live in its own world and only comparing to its history.

  7. No, I do not have such stats. Typically all the stats have been contributed by users in the past. Really, you also have to come up with a workload and implement everything three times, which is a ton of work. On top of that without having a lot of use cases and services the data is not relevent in many cases.
    Just my 2 cents.

Leave a Reply to Peran Cancel reply

Your email address will not be published. Required fields are marked *