如何更快地进行XML反序列化?

我有以下代码

public static object XmlDeserialize(string xml, Type objType)
{
    StringReader stream = null;
    XmlTextReader reader = null;
    try
    {
        XmlSerializer serializer = new XmlSerializer(objType);
        stream = new StringReader(xml);//Read xml data
        reader = new XmlTextReader(stream); //Create reader
        return serializer.Deserialize(reader);
    }
    finally
    {
        if(stream != null) stream.Close();
        if(reader != null) reader.Close();
    }
}

该对象本身是通过xsd.exe生成的,看起来像这样:

/// 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class MyObject {

    private DemographicsCriteriaStateStartAge[] startAgesField;

    private DemographicsCriteriaStateEndAge[] endAgesField;

    private DemographicsCriteriaStateFilter[] selectedFiltersField;

    /// 
    [System.Xml.Serialization.XmlArrayItemAttribute("StartAge", IsNullable=false)]
    public DemographicsCriteriaStateStartAge[] StartAges {
        get {
            return this.startAgesField;
        }
        set {
            this.startAgesField = value;
        }
    }
    ...

该方法通常像这样调用:

var obj = (MyObject) XmlDeserialize(someXmlString, typeof(MyObject));

以下代码行总是花费相当多的时间(与其他所有内容相比):

XmlSerializer serializer = new XmlSerializer(objType);

这里发生了什么,例如它是在后台编译反序列化程序集吗?为什么性能问题?

我该怎么做才能改善这个性能问题?

5
额外
意见: 1
旁注,而不是 try ... finally ,您可以使用使用
额外 作者 svick,

2 答案

是的,它在运行时动态生成序列化程序集。您可以在Visual Studio中更改此行为。转到项目属性和构建部分。 “生成序列化程序集”的设置将其设置为true。这将在您编译时生成类似 YourProject.XmlSerialiser.dll 的文件,并将在运行时停止此瓶颈。

但是,需要注意的一个例外是此设置仅适用于代理类型(例如,Web服务代理等)。要实际强制 Visual Studio 2010 生成常规类型的序列化程序集,必须要么项目文件(.csproj)并从 Sgen 调用或生成一个构建后步骤,以手动调用程序集上的sgen.exe。

5
额外
我有一堆装配。我是否设置主EXE或从属DLL程序集的设置?顺便说一下,我已经完成了所有这些,并且在bin/debug中没有看到任何YourProject.XmlSerialiser.dll文件。
额外 作者 AngryHacker,
我已阅读各种帖子,底线是该设置仅适用于代理类型(例如Web服务代理)。我会更新你的答案。
额外 作者 AngryHacker,
我只使用它与网络代理,似乎有一些争论,这里是否有一个错误 connect.microsoft.com/VisualStudio/feedback/details/123088/… &zwnj ;。有关更精细的控制,请查看此处记录的exe工具 msdn.microsoft.com/en-us/library/bk3w6240(v = VS.80)的.aspx
额外 作者 Ben Robinson,
我认为每个普通装配需要一个序列化装配。
额外 作者 Ben Robinson,

尝试在类级别为每个类型缓存 XmlSerializer 的实例,这样如果使用相同的类型,则不必每次都重新创建它:

class Foo
{
    private static Dictionary xmls = new Dictionary();

   //...

    public static object XmlDeserialize(string xml, Type objType)
    {
        StringReader stream = null;
        XmlTextReader reader = null;
        try
        {
            XmlSerializer serializer;
            if(xmls.Contains(objType)) {
                serializer = xmls[objType];
            }
            else {
                serializer = new XmlSerializer(objType);
                xmls[objType] = serializer;
            }           

            stream = new StringReader(xml);//Read xml data
            reader = new XmlTextReader(stream); //Create reader
            return serializer.Deserialize(reader);
        }
        finally
        {
            if(stream != null) stream.Close();
            if(reader != null) reader.Close();
        }
    }
}
4
额外
当我发现为一个简单的类构造一个XmlSerializer需要多长时间时,这是我的回答。但我认为缓存无论如何都发生在XmlSerializer类中,因为第二次为给定类型创建XmlSerializer时,它不需要花费那么长的时间。
额外 作者 markmuetz,