相关疑难解决方法(0)

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

我在一个有很多字段的类上调用一个简单的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错误所牵制,请不要阅读此内容.

  • 从Visual Studio调试器运行代码使代码即使在64位系统中也能运行FAST
  • 添加(完全未记录的)system.diagnostic开关"XmlSerialization.Compile",防止系统删除序列化临时类,使代码即使在64位系统中运行也很快
  • 获取运行时创建的临时FooXmlSerializer类,包括我项目中的.cs,并使用它代替XmlSerializer,使得代码即使在64位系统中运行也很快
  • 使用sgen.exe创建相同的FooXmlSerializer类,包括我的项目中的.cs,并使用它而不是XmlSerializer,使代码即使在64位系统中运行也很快
  • 使用sgen.exe创建相同的FooXmlSerializer类,在我的项目中引用Foo.XmlSerializers.dll程序集,并使用它而不是XmlSerializer,使得代码在64位系统中运行缓慢(这让我很烦恼)
  • 如果反序列化的输入实际上包含一个大类的字段(这也让我很烦),只会发生性能损失

为了进一步解释最后一点,如果我有一个班级:

[Serializable]
class Bar
{ …
Run Code Online (Sandbox Code Playgroud)

.net 64-bit xmlserializer

22
推荐指数
2
解决办法
6089
查看次数

XmlSerializer不使用sgen创建的XmlSerializers.dll

在我的Visual Studio 2010项目中,我使用以下Post-Build事件命令行来使用sgen来创建XmlSerializers.dll.

发布后事件:

"$(ProgramFiles)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sgen.exe" /a:"$(TargetPath)" /c:/keyfile:"c:\myproject\mykey.snk" /f
Run Code Online (Sandbox Code Playgroud)

我的项目名称很强,所以使用相同的键强名称"XmlSerializers.dll".VS在输出文件夹中创建XmlSerializers.dll.

但是,我注意到使用ProcessMonitor,.NET仍然在运行时调用CSC.exe.我来到这篇帖子,用户有类似的问题,并通过使用XmlSerializer(Type)构造函数解决.

我在我的代码中使用了相同的技术,但它仍然调用csc.exe:

var fs = new FileStream(SettingsFilePath, FileMode.Open);
try
{
var serializer = new XmlSerializer(typeof(AppSettings));
settings = (AppSettings)serializer.Deserialize(fs);
}
finally
{
fs.Close();
}
Run Code Online (Sandbox Code Playgroud)

我需要使用预编译的XML序列化的原因,因为性能和我有时看到Windows关闭时csc.exe错误.我的应用程序在表单关闭时保存数据,在关闭期间,它失败,因为Windows在关闭序列期间不允许新进程启动.我已经看到了通过预编译XML序列化来解决这个问题的建议.

有关为什么XmlSerializer不使用sgen创建的XmlSerializers.dll的任何建议?

谢谢.

.net c# sgen xml-serialization

7
推荐指数
1
解决办法
4189
查看次数

标签 统计

.net ×2

64-bit ×1

c# ×1

sgen ×1

xml-serialization ×1

xmlserializer ×1