How serializers work

Originally posted to Shawn Hargreaves Blog on MSDN, Monday, August 11, 2008

To understand the differences between the XNA Framework IntermediateSerializer and the standard .NET XmlSerializer, it can be useful to look at how they are implemented.

Fundamentally, all serializers work in a similar way:

At a basic level, this is easy stuff. You can write a simple serializer in just one page of C# code.

Trouble is, reflection is SLOOOW. If we actually went through all those steps for every object we encountered, it would take hours to serialize a large and complex object!

To speed things up, the Windows implementation of XmlSerializer uses a radically different approach:

Once you understand this implementation detail, you will release some of the behaviors of XmlSerializer are inevitable results of its design:

When I implemented IntermediateSerializer for the XNA Framework Content Pipeline, I chose a different strategy:

These implementation choices behave a little differently to XmlSerializer:

So which approach is better? Both work. The XmlSerializer implementation is perhaps slightly faster, but my way is more flexible. I suspect one of the main reasons XmlSerializer works the way it does is that it predates the DynamicMethod class, which was added in the 2.0 CLR. I wonder whether the core framework guys would design XmlSerializer the same way today, if they had access to the more powerful and dynamic reflection features of more recent CLR versions.

What about Xbox? It doesn't have Reflection.Emit or DynamicMethod, which is why IntermediateSerializer can only be used during the Content Pipeline build process, and is not available from your runtime Xbox code. But Xbox doesn't have CSharpCodeProvider, either, so how come XmlSerializer works at runtime?

The answer is that the .NET Compact Framework provides an entirely different implementation of XmlSerializer. This has the same API as the Windows version, and generates the same XML, but it does so using regular reflection calls, which are slow and cause a lot of boxing. This is fine for small tasks like loading a config file or saving a hiscore table, but wouldn't work so well for an entire level. Yet another reason why the Content Pipeline precompiles data into XNB format, and avoids trying to deserialize XML at runtime.

Blog index   -   Back to my homepage