问题描述
我遇到一个真正的巨大性能损失,同时调用一个简单的XmlSerializer.Deserizlize()上的一类,有很多领域。
I am experiencing a really HUGE performance loss while calling a simple XmlSerializer.Deserizlize() on a class with lots of fields.
注意:我在写没有Visual Studio中的code,在家里,所以它可能有一些错误
NOTE: I'm writing the code without Visual Studio, at home, so it may have some errors.
我的序列化类是平的,有上百场的:
My serializable class is flat and has hundreds of fields:
[Serializable]
class Foo
{
public Foo() { }
[XmlElement(ElementName = "Field1")]
public string Field1;
// [...] 500 Fields defined in the same way
[XmlElement(ElementName = "Field500")]
public string Field500;
}
我的应用程序反序列化的输入字符串(即使是小):
My application deserializes an input string (even small):
StringReader sr = new StringReader(@"<Foo><Field1>foo</Field1></Foo>");
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
object o = serializer.Deserialize(sr);
运行在32位系统中的应用(或32位被迫与corflags.exe)时,code约需一秒钟第一次(临时序列化类的生成,以及所有... ),那么它的接近为0。
Running the application in 32bit systems (or with 32bit forced with corflags.exe), the code takes about ONE SECOND the first time (temp serialization class generation, and all...), then it's close to 0.
运行在64位系统中的应用,code采用一分钟第一次,那么它的接近0。
Running the application in 64bit systems, the code takes ONE MINUTE the first time, then it's close to 0.
什么可能导致系统挂起的这么长的时间的,一个XmlSerializer的第一个执行过程中,一大类,在64位系统?
What could possibly hang the system for such a long time, during the first execution of an XmlSerializer, for a big class, in a 64bit system?
现在,我不知道如果我要责怪临时类生成/删除,XML名称表初始化,中科院,Windows搜索,防病毒软件,或者圣诞老人...
Right now I'm not sure if I have to blame temp class generation/remove, xml name table initialization, CAS, Windows Search, AntiVirus, or Santa Claus...
剧透
下面是我的测试,不看这个,如果你不希望我的(可能)易观失误所牵制。
Here are my tests, don't read this if you don't want to be sidetracked by my (possible) analysys mistakes.
- 运行code中的从Visual Studio调试器使得code跑得快,即使在64位系统上
- 添加(完全无证)system.diagnostic开关XmlSerialization.Compile,其中$ P $从取出的序列化温度类pvents系统,使得code跑得快,即使在64位系统上
- 以在运行时创建的临时FooXmlSerializer类,包括在我的项目中的.cs,并使用XmlSerializer它代替,使得code跑得快,即使在64位系统上
- 在创建具有sgen.exe相同FooXmlSerializer类,包括在我的项目中的.cs,并使用XmlSerializer它代替,使得code跑得快,即使在64位系统上
- 在创建具有sgen.exe相同FooXmlSerializer类,在我的项目引用Foo.XmlSerializers.dll组装,并使用XmlSerializer它代替,使得code运行慢,即使在64位系统(这个错误我很多)
- 的性能损失只发生在输入实际反序列化包含大类的领域(这也来烦我了很多)
- Running the code the from Visual Studio debugger makes the code run FAST even in 64 bit systems
- Adding the (totally undocumented) system.diagnostic switch "XmlSerialization.Compile", which prevents the system from removing the serialization temp classes, makes the code run FAST even in 64 bit systems
- Taking the temp FooXmlSerializer class created by the runtime, including the .cs in my project, and using it instead of the XmlSerializer, makes the code run FAST even in 64 bit systems
- Creating the same FooXmlSerializer class with sgen.exe, including the .cs in my project, and using it instead of the XmlSerializer, makes the code run FAST even in 64 bit systems
- Creating the same FooXmlSerializer class with sgen.exe, referencing the Foo.XmlSerializers.dll assembly in my project, and using it instead of the XmlSerializer, makes the code run SLOW even in 64 bit systems (this bugs me a lot)
- The performance loss only happens if the input to deserialize actually contains a field of the big class (this also bug me a lot)
要进一步说明的最后一点,如果我有一个类:
To further explain the last point, if I have a class:
[Serializable]
class Bar
{
public Bar() { }
[XmlElement(ElementName = "Foo")]
public Foo Foo; // my class with 500 fields
}
传递一个富孩子,只有当该反序列化是缓慢的。即使我已经进行了反序列化:
The deserialize is slow only when passing a Foo child. Even if I already performed a deserialization:
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
修改我忘了说,我分析了进程监视器的执行,我没有看到任何任务花费很长的时间,从我的应用程序或csc.exe的,或任何框架相关的。该系统只是做其他的东西(或者我失去了一些东西),如防病毒,Explorer.exe的,Windows搜索索引(已试图将其关闭)
EDIT I forgot to say that I analyzed the execution with Process Monitor, and I don't see any task taking a long time from my app or from csc.exe, or anything Framework-related. The system just does other stuff (or I am missing something), like antivirus, explorer.exe, Windows Search indexing (already tried to turn them off)
推荐答案
我不知道这是在所有相关的,但我有一个问题,XSLT,发现those 通过微软对64位抖动而有趣的评论:
I don't know if this is related at all, but I had an issue with XSLT and found those rather interesting comments by Microsoft about the 64-Bit JITter:
这个问题的根源是相关的两件事情:第一,64 JIT编译器有一些算法是二次缩放。其中之一是调试信息生成器,很遗憾。因此,对于非常大的方法,它真的失控了。
[...]
在64位JIT有多项式缩放某些算法。我们实际上正在移植的32位JIT编译器到x64,但不会看到光明的一天,直到的下一步的一侧并排放出的运行时(如在2.0安培; 4.0运行并排侧,但3.0 / 3.5 / 3.5SP1是'就地'版本),我这个切换切换到建议,这样我就可以把它贴在JIT吞吐量的工作项。确保新移植的JIT是准备出货,这是固定的。
some algorithms in the 64 bit JIT that have polynomial scaling. We're actually working on porting the 32 bit JIT compiler to x64, but that won't see the light of day until the next side-by-side release of the runtime (as in "2.0 & 4.0 run side-by-side, but 3.0/3.5/3.5SP1 were 'in-place' releases). I've switched this over to a 'suggestion' so I can keep it attached to the JIT-throughput work item to make sure this is fixed when the newly ported JIT is ready to ship.
这又是另一个完全不同的问题,但在我看来,64位抖动的意见是普遍的。
Again, this is about a completely different issue, but it appears to me that the 64-Bit JITter comments are universal.
这篇关于在64位系统的XmlSerializer启动巨大的性能损失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!