I've written about Mike Talbot's SilverlightSerializer before. Mike's page on it is here.
Silverlight Serializer can serialize and rehydrate just about anything, including
complex multi-dimensional arrays of complex objects. By default it can only serialize
public fields and properties for classes with a parameterless constructor however
you can handle events to construct objects that require parameters for construction
and you can write a custom serializer for a particular type.
The serializer can also produce Checksums that can be used to compare different objects
to see if they have the same meaning, or to use as keys to see if you have a
cached version already available.
Silverlight Serializer can be used to send information to and from a server using
WCF or an ASHX, to create undo buffers for your app or to save things to the
file system on either Silverlight or .NET. You can also use it to deep copy
In some basic performance testing on .NET4 it proved comparable to BinaryFormatter
when serializing (slightly slower), produced files about 30% of the size of those
created by BinaryFormatter and deserializes 60% faster.
Silverlight Serializer is thread safe.
What I have done here is to create a solution that contains both a Test console app,
and the source code for SilverlightSerializer, along with a copy of the QuickLZ
compression codec (which is also Silverlight compatible).
The idea was to creat a List<T> of 100 objects (a Person class that has an
IList<Address> property), serialize it, compress that, then decompress
and deserialize it as a proof of concept. I created test code for both SilverlightSerializer
and the .NET Framework BinaryFormatter to compare both speed and size of the
compressed byte arrays, as well as comparing the DataContractSerializer.
You can set a Full Framework 4.0 reference to a Silverlight assembly and it will
work, but you have to do it using the Browse feature and browse directly to the
compiled assembly. As long as the Silverlight assembly only references Mscorlib,
System, and System.Core, it will be full-framework compatible. What this means
is that you can handle serialization and compression in your Silverlight application,
send the byte array over the wire to a WCF Service that uses the full Framework,
and it will be able to use the same code to perform serialization / deserialization,
and compression / decompression.
Each of my tests serializes a List<Person> containing 100 instances, compresses
it, then decompresses and deserializes. Each full operation is timed, and the
size of the stored compressed byte array is measured. Here are the results of
SilverightSerializer: 196 ms 2863 bytes
BinaryFormatter: 129 ms 7651 bytes
DataContractSerializer: 932 ms 3800 bytes
The SilverlightSerializer is a bit slower than the BinaryFormatter (mostly during
the serialization process), but it produces a byte array only 37 percent as large.
This is especially ideal when you consider that the DataContractSerializer, which
is the standard means of serialization for WCF, produces a byte array of comparable
size, but takes nearly five times as long as the SilverlightSerializer for the
Here is the test code, and you can download the complete solution at the bottom:
static void Main(string args)
List<Person> people = new List<Person>();
for (int i = 0; i < 100; i++)
Person p = new Person();
p.FirstName = "Joe";
p.LastName = "Lastname" + i.ToString();
p.Id = i;
p.Email = "joe" + i.ToString() + "@bork.com";
p.Phone = "1234564444";
List<Address> addresses = new List<Address>();
for (int j = 0; j < 2; j++)
Address a = new Address();
a.AddressType = "Type" + i.ToString();
a.City = "MyCity";
a.State = "FL";
a.Street = "12 North Street";
a.Zipcode = "32101";
p.Addresses = addresses;
// Use Silverlight Serializer:
Stopwatch sw = Stopwatch.StartNew();
byte b= SilverlightSerializer.Serialize(people);
byte b2= b.Compress();
byte b3 = b2.Decompress();
List<Person> newPeople =(List<Person>) SilverlightSerializer.Deserialize(b3);
Console.WriteLine(" ms: size:" );
Console.WriteLine( "SLSerializer: " +sw.ElapsedMilliseconds + " " +b2.Length );
// Use BinaryFormatter:
Stopwatch sw2 = Stopwatch.StartNew();
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
byte b4 = ms.ToArray();
byte b5 = b4.Compress();
byte b6 = b5.Decompress();
MemoryStream ms2 = new MemoryStream(b6);
List<Person> newPeople2 = (List<Person>) bf.Deserialize(ms2);
Console.WriteLine( "Binary Formatter: " +sw2.ElapsedMilliseconds + " "+ b5.Length );
Stopwatch sw3 = Stopwatch.StartNew();
DataContractSerializer dcs = new DataContractSerializer(typeof(List<Person >));
MemoryStream ms3 = new MemoryStream();
byte b7 = ms3.ToArray();
byte b8 = b7.Compress();
byte b9 = b8.Decompress();
MemoryStream ms4 = new MemoryStream(b9);
List<Person> people2 =(List<Person>)dcs.ReadObject(ms4);
Console.WriteLine("DataContract: " + sw3.ElapsedMilliseconds + " " + b8.Length);
You can download the complete Visual Studio 2010 solution here.
NOTE: This code uses Silverlight 5. You can download the required runtime and Tools here.