Maybe it’s just me, but it seems to be known that XmlSerializer is way, way, way, way, way, way slower than the Binary or SOAP serializers in .NET. I took that at face value and never really looked more into it than that.
I’m working on a project at work for a audit service, in fact with Jamie. The component we’re building basically allows the consuming developer to populate some data structures, we then serialize them into XML, then put the result on an IBM Message Queue (MQ).
The problem comes in, when we ran into ridiculously slow performance – like, 2 seconds to just serialize the data structures! Worse, it’s mostly from exactly one line of code, and that’s when you actually go to serialize the object, using XmlSerializer.Serialize(). If you google that (or bing it) you’ll find plenty of blogs that talk about using sgen.exe to generate the serialization assembly ahead of time – but no one really talked about how serialization works behind the scenes and why it is so much slower. I whipped up a test rig to compare timings and came up with staggering numbers like this:
So basically, serializing with the XmlSerializer was taking at LEAST a 10th of a second, best-case-scenario. So I looked into this a bit and read about how when you go to this serialization object, the run-time: generates code, compiles it, then references and uses what it just made! Egads, of course this is going to be slow!
In our case, we were creating a new instance of XmlSerializer for every message we needed to process. That means we’re added 1/10th of a second on to every call. This is not really acceptable. However, now that we know how serialization works, the answer is simple! We simply need to create the instance the XmlSerializer once, then we can simply re-use it. Even better – you can go back to all those blog posts that explain how to use sgen.exe to pre-compile these assemblies if you need that. So understanding the problem, one can address the initial slowness (by pre-compiling the dynamic serialization assembly) and/or address the subsequent calls being slow (by re-using the XmlSerialization instance).
What was the result? Well, by simply re-using the same XmlSerializer instance, we took the hit on the first call (which is expected), but then subsequent calls were very fast! Here are the results of that:
As you can see, running in less than a millisecond is not bad, in terms of overhead that we’re adding to the developers code. So, since I wasn’t aware of how serialization worked before this, I thought I would write this up in hopes it might help someone else!