Fil*_*ini 22 .net 64-bit xmlserializer
我在一个有很多字段的类上调用一个简单的XmlSerializer.Deserizlize()时遇到了巨大的性能损失.
注意:我在家里没有Visual Studio编写代码,因此可能会有一些错误.
我的可序列化类是扁平的,有数百个字段:
[Serializable]
class Foo
{
public Foo() { }
[XmlElement(ElementName = "Field1")]
public string Field1;
// [...] 500 Fields defined in the same way
[XmlElement(ElementName = "Field500")]
public string Field500;
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序反序列化输入字符串(甚至很小):
StringReader sr = new StringReader(@"<Foo><Field1>foo</Field1></Foo>");
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
object o = serializer.Deserialize(sr);
Run Code Online (Sandbox Code Playgroud)
运行在32位系统中的应用(或32位被迫corflags.exe),代码需要大约一秒钟的第一次(临时序列化类的生成,和所有的...),那么它的接近0.
在64位系统中运行应用程序,代码第一次占用一分钟,然后接近0.
在第一次执行XmlSerializer期间,对于大型类,在64位系统中,可能会将系统挂起这么长时间?
现在我不确定是否必须责怪临时类生成/删除,xml名称表初始化,CAS,Windows搜索,AntiVirus或圣诞老人......
破坏者
以下是我的测试,如果您不想被我(可能的)analysys错误所牵制,请不要阅读此内容.
为了进一步解释最后一点,如果我有一个班级:
[Serializable]
class Bar
{
public Bar() { }
[XmlElement(ElementName = "Foo")]
public Foo Foo; // my class with 500 fields
}
Run Code Online (Sandbox Code Playgroud)
只有在传递Foo子项时,反序列化才会很慢.即使我已经执行了反序列化:
StringReader sr = new StringReader(@"<Bar></Bar>");
XmlSerializer serializer = new XmlSerializer(typeof(Bar));
object o = serializer.Deserialize(sr); // FAST
StringReader sr = new StringReader(@"<Bar><Foo><Field1>foo</Field1></Foo></Bar>");
XmlSerializer serializer = new XmlSerializer(typeof(Bar));
object o = serializer.Deserialize(sr); // SLOW
Run Code Online (Sandbox Code Playgroud)
编辑我忘了说我用Process Monitor分析了执行情况,我没有看到任何任务花了很长时间从我的应用程序或csc.exe,或任何与框架相关的任务.系统只做其他事情(或者我遗漏了一些东西),比如防病毒,explorer.exe,Windows搜索索引(已经尝试关闭它们)
我不知道这是否相关,但我遇到了XSLT的问题,并发现了微软关于64位JITter的那些有趣的评论:
问题的根源与两件事有关:首先,x64 JIT编译器有一些二次缩放的算法.其中一个是调试信息生成器,不幸的是.所以对于非常大的方法,它确实失控了.
[...]
64位JIT中的一些算法具有多项式缩放.我们实际上正在努力将32位JIT编译器移植到x64,但是直到下一个并行发布的运行时才能看到它的亮点(如"2.0和4.0并行运行") ,但3.0/3.5/3.5SP1是'就地'版本..我已经将其转换为'建议',所以我可以将它附加到JIT吞吐量工作项,以确保在新的时候修复它移植JIT已准备好发货.
同样,这是一个完全不同的问题,但在我看来,64位JITter评论是通用的.
更新:
我能够重现这一点,调查显示大部分时间花在了JIT编译器上:
JittingStarted:"Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderFoo","Read2_Foo","实例类SerializersTester.Foo"
您可以轻松证明没有任何分析器工具.
您可以注意到与x86程序集相比,x64生成速度要慢得多
确切的原因隐藏在x64 JIT内部(BTW它与x86完全不同),遗憾的是我没有足够的业余时间来找到它.
为了避免这种性能损失,您可以通过sgen生成序列化程序的程序集,引用它并在最终用户PC上的应用程序设置期间通过ngen编译为本机映像.