.net - XmlSerializer启动在64位系统上的巨大性能损失

标签 .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;
}

我的应用程序反序列化输入字符串(甚至很小):
 StringReader sr = new StringReader(@"<Foo><Field1>foo</Field1></Foo>");
 XmlSerializer serializer = new XmlSerializer(typeof(Foo));
 object o = serializer.Deserialize(sr);

在32位系统(或使用corflags.exe强制使用32位)上运行该应用程序时,代码第一次大约需要一个二级(临时序列化类生成,以及所有...),然后接近0。

在64位系统上运行该应用程序,该代码第一次将设为ONE MINUTE ,然后接近0。

对于64位系统中的大型类,在首次执行XmlSerializer的过程中,对于这么大的类,有什么可能使系统挂那么长时间?

现在,我不确定是否要怪临时类的生成/删除,xml名称表初始化,CAS,Windows Search,AntiVirus或圣诞老人...

SPOILERS

这是我的测试,如果您不想被我(可能)的analysys错误所困扰,请不要阅读此内容。
  • 从Visual Studio调试器运行代码,即使在64位系统中,代码也可以快速运行
  • 添加(完全未记录)system.diagnostic开关“XmlSerialization.Compile”,可以防止系统删除序列化临时类,即使在64位系统中,该代码也可以运行FAST。
  • 采取由运行时创建的临时FooXmlSerializer类(包括我的项目中的.cs),并使用它代替XmlSerializer,即使在64位系统中,代码也可以快速运行
  • 使用sgen.exe创建相同的FooXmlSerializer类,包括我项目中的.cs,并使用它代替XmlSerializer,即使在64位系统中,代码也可以快速运行
  • 使用sgen.exe创建相同的FooXmlSerializer类,在我的项目中引用Foo.XmlSerializers.dll程序集,并使用它而不是XmlSerializer来使代码即使在64位系统中也运行缓慢(这使我感到很不舒服)
  • 仅当要反序列化的输入实际上包含一个大类的字段时才发生性能损失(,这也会给我带来很多的麻烦)

  • 为了进一步解释最后一点,如果我有课的话:
    [Serializable]
    class Bar
    {
        public Bar() { }
    
        [XmlElement(ElementName = "Foo")]
        public Foo Foo; // my class with 500 fields
    }
    

    仅当通过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
    

    编辑我忘了说我使用Process Monitor分析了执行情况,并且看不到任何任务需要花费很长时间从我的应用程序或csc.exe或与框架相关的任何事情。系统只是做其他事情(或者我缺少什么),例如防病毒,explorer.exe,Windows搜索索引(已经尝试将其关闭)

    最佳答案

    我根本不知道这是否相关,但是我在XSLT上遇到了一个问题,并且发现了Microsoft关于64位JITter的those rather interesting comments:

    The root of the problem is related to two things: First, the x64 JIT compiler has a few algorithms that are quadratically scaling. One of them is the debug info generator, unfortunately. So for very large methods, it really gets out of control.

    [...]

    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位Jitter注释是通用的。

    关于.net - XmlSerializer启动在64位系统上的巨大性能损失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4137335/

    相关文章:

    .net - 如何选择一个开源项目加入?

    windows - 将整个注册表导出到相对路径

    在 C 中计算 64x64 int 产品的高 64 位

    Java - 64 位系统的类路径问题

    c# - 无法将 XML 反序列化为 C# 对象,我做错了什么?

    javascript - 标签文本框服务器控件

    c# - 使用印度编号系统的逗号分隔符格式化数字字符串

    c# - 从 XML 更新插入 SQL Server 表

    c# - 使用 XmlInclude 或 SoapInclude 属性指定静态未知的类型

    c# - 使用代码默认值对集合属性进行 XML 反序列化