XmlSerializer语言 - 第一次反序列化非常慢



我有一个包含两个项目的解决方案:一个 asp.net MVC应用程序和一个类库。我们称它们为项目 MVC 和项目 CLS。

在项目 CLS 中,有两个不同版本的 XSD 文件(V1 和 V2(,我使用这些版本使用 xsd2code 创建两个具有相同名称但位于不同命名空间(V1 和 V2(下的可序列化类。

在 MVC 项目中,当用户上载 XML 文件时,CLS.dll用于将 XML 反序列化为对象。当 XML 文件的类型为 V1 时,反序列化非常快,但 V2 版本的 XSD 文件要复杂得多,反序列化可能需要几分钟,只是第一次(之后非常快,直到应用程序再次运行(。

我使用 Sgen.exe 工具为 CLS 创建了一个序列化程序程序集 (CLS.XmlSerializers.dll(。V2型以省去了第一次创建组件的动态,从而提高了性能。

我已经成功地将 Sgen 任务添加到后期构建事件中,并且每次构建项目时都会创建程序集CLS.XmlSerializers.dll。此外,我在这篇文章中使用了单元测试代码来确保程序集已加载,并且确实如此。测试通过。

但是,第一次反序列化 XML 文件时,仍然需要很长时间。所以,仍然应该有问题。但是,我不知道是什么。请帮忙。

更新:

我按照评论中的建议使用了Fuslogvw.exe,我可以看到CLS.XmlSerializers.dll已成功加载。那么,为什么第一次反序列化 XML 文件大约需要一分钟,但之后每次都需要不到一秒钟?

更新 2:

两个 XSD 文件之间的区别之一是第二个 (V2( 引用了一个非常大的 XSD 文件,该文件包含主文件中使用的一些xs:enumeration类型的定义。而且,这就是反序列化花费很长时间的原因。由于我需要做的就是将 XML 文件反序列化为对象,并且不需要根据这些枚举验证属性和元素的值,因此我最终删除了对该 XSD 文件的引用,并将所有枚举类型替换为其基类型(在本例中为xs:string(。现在,V2 的反序列化速度与 V1 一样快,我什至不需要使用Sgen.exe.我想Sgen.exe仅在您需要反序列化非常大的 XML 文件的情况下有所帮助。就我而言,XML 文件总是非常小,但设计(曾经(很复杂。

为了提高 XML 序列化的性能,每次首次为特定类型实例化 XmlSerializer 时,都会动态生成程序集。它在应用程序生命周期中只发生一次,但这会使它的第一次使用速度变慢。

实例化 XmlSerializer 时,必须传递将尝试使用该序列化程序实例进行序列化和反序列化的对象的类型。序列化程序检查 Type 的所有公共字段和属性,以了解实例在运行时引用哪些类型。然后,它继续为一组类创建 C# 代码,以使用 System.CodeDOM 命名空间中的类处理序列化和反序列化。在此过程中,XmlSerializer 检查 XML 序列化属性的反射类型,以便将创建的类自定义为 XML 格式定义。然后将这些类编译为临时程序集,并由 Serialize(( 和 Deserialize(( 方法调用以执行 XML 到对象的转换。

完整内容:解决 XML 序列化程序的常见问题

详细信息:XML 序列化程序构造函数性能问题

这是 x64 jit 编译器的已知问题,在某些情况下可能会非常慢。这就是为什么在代码已经编译后第二次运行反序列化时性能更好的原因。

尝试使用.net 4.6或更高版本,它具有新版本的x64 jit编译器(RyuJIT(。如果无法更新 .net 版本,请查看此线程。

最新更新