.NET 2中XmlSerializer不同构造函数致性能骤降的原因探究
问题:XmlSerializer构造函数选择导致性能差异的原因
在.NET 2环境下,以下代码运行正常:
public static T DeserializeStream<T>(this Stream xmlStream) { XmlSerializer serializer = new XmlSerializer(typeof(T)); using (XmlReader xmlReader = XmlReader.Create(xmlStream)) { return (T)serializer.Deserialize(xmlReader); } }
但当改用更具体的构造函数并传入空值(如下所示)后,处理同类型的大量文件时,代码运行速度至少慢5倍:
XmlSerializer serializer = new XmlSerializer(typeof(T), null, Type.EmptyTypes, null, null);
请问这是什么原因?是否属于预期情况?这会阻止某种类型数据的缓存吗?
解答
核心原因:缓存机制差异
.NET的XmlSerializer对使用仅传入Type参数的构造函数创建的序列化器实例,会自动进行全局缓存。当你多次为同一T类型创建序列化器时,实际复用的是同一个缓存实例,省去了重复生成序列化代码、编译动态程序集的巨大开销。带参数构造函数变慢的本质
当你使用包含额外参数(哪怕传入null或Type.EmptyTypes这类默认等效值)的构造函数时,.NET会将这些参数作为缓存键的一部分。哪怕参数值看起来和默认构造的场景一致,也会被判定为不同的创建条件。因此每次调用这个构造函数时,都会重新生成并编译对应类型的序列化程序集,这部分操作的耗时直接导致处理大量文件时性能暴跌5倍以上。是否属于预期情况?
是的,这是XmlSerializer的设计行为。默认缓存逻辑仅针对无额外自定义配置的极简场景,一旦使用带参数的构造函数(无论参数是否为默认值),都会绕过默认缓存机制。对缓存的影响
没错,这种写法完全阻止了针对该T类型的序列化器缓存。每次创建实例都要执行动态代码生成、程序集编译的流程,这就是性能骤降的核心原因。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

