Out of the box Silverlight provides two message encoding types for sending SOAP messages over the wire. These are TextEncoding and BinaryEncoding. MTOM encoding is still not available within Silverlight.
Binary encoded messages produce a payload that is about half the size of a message encoded with standard text encoding. Please note that binary encoding is a Microsoft proprietary implementation and therefore not interoperable outside the .NET framework.
In our Silverlight applications we use a .NET to .NET messaging scenario (like many other SL apps too), which means Silverlight communicates with a WCF backend. Using then binary encoded messages is obvious.
You will find a lot of blog posts out there in the community when you are interested in binary vs. text-encoding comparison.
What exactly does BinaryEncoding?
When the encoding is set to binary, then the DataContractSerializer still produces SOAP messages as XML but after that the messages get transformed into a binary representation of the XML with help of the XmlDictionaryWriter class.
The following code snippet shows the usage of the XmlDictionaryWriter class (not WCF related).
You should not compare the XmlDictionaryWriter with the well-known BinaryFormatter in the mscorlib. The BinaryFormatter produces a binary representation of an object graph. The XmlDictionaryWriter on the other hand translates a textual XML into a binary representation. Serializing a XML string with the BinaryFormatter will not reduce the size, because the XML is just a single string from this point of view.
The textual output form the example above indicates that it is a kind of an optimized XML structure.
Optimize Data Contracts
Binary XML still includes the names of the elements and attributes as plain text.
When setting the name of my data contracts to a single character then the SOAP message size will be reduced by additional 30-50 percent (depends on the data structure).
The SOAP-Envelop then look like this:
Rules for setting the name:
- Each data contract must have a unique name in the scope of its namespace
- Each data member must have a unique name in the scope of its class.
- Use character [A-Za-z], you can mix upper and lower case.
After these changes the generated proxy on client side is quite unhandy, because the classes and members are named like they are declared in the contracts. Therefore I created a shared lib and reuse the data contracts on client side.
Assemblies built in Silverlight are in general not binary compatible with the .NET Framework, so if you want to share code you need to dual-compile your code. Since Silverlight 4 you will be able to use some Silverlight-based assemblies from within .NET 4. In order to load a Silverlight assembly in .NET, the assembly may only reference the following assemblies: mscorlib.dll, System, System.Core.dll, System.ComponentModel.Composition.dll, Microsoft.VisualBasic.dll.
Well, my shared data contracts dll needs a reference to System.Runtime.Serialization.dll which is currently not binary compatible with the Silverlight runtime.
Therefore I do a dual-compile by adding the same source file with “Add As Link” to my Silverlight library.
As final task I add a reference to SharedDataContract.SL assembly and update my service reference. Please check that the option “Reuse types in referenced assemblies” is checked.
Comparison of different configurations
Text encoding / standard contract
Text encoding / optimized contracts
Binary encoding / standard contracts
Binary encoding / optimized contracts
Summary
When communicating in a .NET to .NET messaging scenario then optimizing the data contracts is an additional way to reduce the SOAP message size. This together with binary encoding will reduce the message size about 4 times. Especially looking to the Windows Phone 7 development this will help when the traffic goes over a low bandwidth network.
How you actually measured the speed difference ? Smaller packets do not automatically mean higher speed.
Have you tried protobuf insted of WCF ?
Protobuf is optimized for performance unlike WCF which is still based in slow xml. There is excellent protobuf implementation for Silverlight client in google code written by Marc Gravell.
Yes, I agree with you that the speed doesn’t depend only on the packed size. Maybe I should say that we use our client over a low bandwidth network such as the GSM mobile network. In such an environment the package size will play a bigger bottleneck as over a high-speed internet or intranet connection.
No, I didn’t know Protobuf before. Thank you for this hint, I will check it.
In WCF binary protocol announcment MS states that binary protocol does not increase response speed if server overload is slow. About protobuf, thare was recently article in Codeproject about using one implementation of it in Silverlight and we discussed it there with its author March Gravell. For me it seems that protobuf does not increase speed but requires more coding. In my test ( http://forums.silverlight.net/forums/p/183753/418152.aspx) data retrieval takes 0.2 seconds, communication overhead 0.2 seconds, DataGrid rendering with predefined height 0.3 seconds or 0.9 seconds if no height predefined. Protobuf can teoretically decrease only this 0.2 sec communication overhead. Not sure will it actually decrease it.
Thank a lot for this article!
Appreciate!
[...] http://www.askives.com/wcf-performance.html http://blog.thekieners.com/2010/05/04/optimize-data-contracts-for-better-wcf-performance/ http://merill.net/2008/10/wcf-performance-optimization-tips/ [...]
BookGrill – download free books
Download here free books
Greetings! I’ve been reading your blog for a while now and finally got the courage to go ahead and give you a shout out from Austin Texas! Just wanted to mention keep up the good work!