XmlSerializer 构造函数的性能有关问题
关键字:XmlSerializer, Performace Issue
近日在解决一个性能问题时,发现如下这段代码的执行要花费较长的时间
通过使用DebugViewer查看,发现上面蓝色加粗的代码占用了较长的时间,代码实现如下
最终发现上面加粗的两行代码占用了较多时间,通过查阅一些资料发现,XmlSerializer在实例化时会根据其构造函数中的Type参数产生临时的assemblies来进行序列化或者反序列化的工作,从来提高效率,但是如果构造函数选用的不当,就会有内存泄露和性能问题。当使用下面的构造函数时,.NET会重用临时产生的assemblies
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
但是,如果使用其他的构造函数则会生成同一个临时assembly的多个不同版本,即第一次调用XmlSerializer的构造函数时临时生产一个版本的assembly A,第二次调用XmlSerializer的构造函数时会生成A的另一个版本,第三次调用XmlSerializer的构造函数时会生成A的第三个版本。。。而之前生成的临时版本还不会被卸载,从而就导致了内存泄露和性能问题
上面的代码使用了XmlSerializer(Type, XmlRootAttribute)构造函数,所以才导致了性能问题
详细说明参见XmlSerializer Class in MSDN,内容摘录如下:
Dynamically Generated Assemblies
To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types. The infrastructure finds and reuses those assemblies. This behavior occurs only when using the following constructors:
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance. The easiest solution is to use one of the previously mentioned two constructors. Otherwise, you must cache the assemblies in a Hashtable
解决办法:
使用Dictionary将第一次实例化的XmlSerializer对象存起来,使用其构造函数的参数作为Key,以后再对同样的Type实例化XmlSerializer时直接从Dictionary中取,改进后的代码
使用
这样就大大提升了性能
参考链接:
http://www.damirscorner.com/XmlSerializerConstructorPerformanceIssues.aspx
http://blogs.msdn.com/b/crm/archive/2009/02/02/boost-performance-with-pre-generated-xmlserializers.aspx
http://mikehadlow.blogspot.com/2006/11/playing-with-xmlserializer.html
XmlSerializer Performance Issue when Specifying XmlRootAttribute