如何让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 生成的,看起来有点像这样:
/// <remarks/>
[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;
/// <remarks/>
[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);
这里发生了什么,例如它是否在后台编译反序列化程序集?为什么会出现性能问题?
我可以做什么来改善这个性能问题?
I have the following piece of code
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();
}
}
The object itself has been generated via xsd.exe and looks kind of like this:
/// <remarks/>
[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;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("StartAge", IsNullable=false)]
public DemographicsCriteriaStateStartAge[] StartAges {
get {
return this.startAgesField;
}
set {
this.startAgesField = value;
}
}
...
The method is typically called like this:
var obj = (MyObject) XmlDeserialize(someXmlString, typeof(MyObject));
The following line of code always take a pretty large chunk of time (compared to everything else):
XmlSerializer serializer = new XmlSerializer(objType);
What is going on here, e.g. is it compiling a deserialization assembly in the background? Why the performance issue?
What can I do to ameliorate this performance problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试在类级别缓存每种类型的
XmlSerializer
实例,这样如果使用相同的类型,则不必每次都重新创建它:Try caching the instance of the
XmlSerializer
for each type at the class level so you don't have to recreate it each time if the same type is used:是的,它在运行时动态生成序列化程序集。您可以在 Visual Studio 中更改此行为。转到项目属性和构建部分。有一个“生成序列化程序集”的设置,将其设置为 true。当您编译时,这将生成一个类似
YourProject.XmlSerialiser.dll
的文件,并将在运行时阻止此瓶颈。然而,需要注意的一个例外是,此设置仅适用于代理类型(例如,Web 服务代理等)。要真正强制 Visual Studio 2010 为常规类型生成序列化程序集,必须要么搞乱项目文件 (.csproj) 并从 Sgen 调用或生成构建后步骤在程序集上手动调用 sgen.exe。
Yes, it is dynamically generating a serialisation assembly at run time. You can change this behaviour in Visual Studio. Go to the project properties and the build section. There is a setting for "Generate serialization assemblies" set it to true. This will generate a file like
YourProject.XmlSerialiser.dll
when you compile and will stop this bottleneck at run time.One exception to note, however, is that this setting applies only to proxy types (for example, web service proxies and the like). To actually force Visual Studio 2010 to generate serialization assemblies for regular types, one must either mess with the project file (.csproj) and remove /proxytypes from the Sgen call or generate a post-build step to manually call sgen.exe on the assembly.