XmlSerializer 构造函数的性能问题
2012-06-21 09:15
232 查看
关键字:XmlSerializer, Performace Issue
近日在解决一个性能问题时,发现如下这段代码的执行要花费较长的时间
通过使用DebugViewer查看,发现上面加log之间的的代码占用了较长的时间,代码实现如下
最终发现上面加log的两行代码占用了较多时间,通过查阅一些资料发现,XmlSerializer在实例化时会根据其构造函数中的Type参数产生临时的assemblies来进行序列化或者反序列化的工作,从来提高效率,但是如果构造函数选用的不当,就会有内存泄露和性能问题。当使用下面的构造函数时,.NET会重用临时产生的assemblies
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type,String)
但是,如果使用其他的构造函数则会生成同一个临时assembly的多个不同版本,即第一次调用XmlSerializer的构造函数时临时生产一个版本的assemblyA,第二次调用XmlSerializer的构造函数时会生成A的另一个版本,第三次调用XmlSerializer的构造函数时会生成A的第三个版本。。。而之前生成的临时版本还不会被卸载,从而就导致了内存泄露和性能问题
上面的代码使用了XmlSerializer(Type,XmlRootAttribute)构造函数,所以才导致了性能问题
详细说明参见XmlSerializer Class in MSDN,内容摘录如下:
Dynamically GeneratedAssemblies
Toincrease performance, the XML serialization infrastructure dynamically generatesassemblies to serialize and deserialize specified types. The infrastructurefinds and reuses those assemblies. This behavior occurs only when using thefollowing constructors:
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
Ifyou use any of the other constructors, multiple versions of the same assemblyare generated and never unloaded, which results in a memory leak and poorperformance. The easiest solution is to use one of the previously mentioned twoconstructors. Otherwise,
you must cache the assemblies in a
Hashtable
解决办法:
使用Dictionary将第一次实例化的XmlSerializer对象存起来,使用其构造函数的参数作为Key,以后再对同样的Type实例化XmlSerializer时直接从Dictionary中取,改进后的代码
使用
XmlSerializerxmlSerializer = new XmlSerializer(ObjectType, rootAttr);
// 按照如下方式使用
XmlSerializerxmlSerializer = GetSerializer(ObjectType, rootAttr);
这样就大大提升了性能
参考链接:
http://www.damirscorner.com/XmlSerializerConstructorPerformanceIssues.aspx
http://blogs.msdn.com/b/crm/archive/2009/02/02/boost-performance-with-pre-generated-xmlserializers.aspx
http://mikehadlow.blogspot.com/2006/11/playing-with-xmlserializer.html
Playing with the XmlSerializer
XmlSerializer Performance Issue when SpecifyingXmlRootAttribute
近日在解决一个性能问题时,发现如下这段代码的执行要花费较长的时间
SuperElement = XElement.Parse(xmlcontent from resource file); // 获取指定的内容 IEnumerable<XElement> elements= SuperElement.Descendants().Where( elem => elem.Name =="Element Name" && elem.Attribute("Target") != null); //ObjectA就是要进行反序列化的类名 m_objectList = newList<ObjectA>(); // 遍历,然后逐一进行反序列化 int logCounter = 1; foreach (XElement element inelements) { System.Diagnostics.Trace.TraceInformation("deserialize2.{0} begin", logCounter); ObjectAobj = ObjectASerializer<ObjectA>.LoadFromXElement(element); System.Diagnostics.Trace.TraceInformation("deserialize 2.{0} end", logCounter++); m_objectList.Add(obj); }
通过使用DebugViewer查看,发现上面加log之间的的代码占用了较长的时间,代码实现如下
public static TLoadFromXElement(XElement element) { int logCounter = 0; T serializableObject = null; Type ObjectType = typeof(T); XmlRootAttribute rootAttr = newXmlRootAttribute(); rootAttr.ElementName =element.Name.ToString(); rootAttr.IsNullable = true; System.Diagnostics.Trace.TraceInformation("LoadFromXElement Beforector {0}", logCounter++); XmlSerializer xmlSerializer = newXmlSerializer(ObjectType, rootAttr); System.Diagnostics.Trace.TraceInformation("LoadFromXElementAfter ctor {0}", logCounter++); using (XmlReader xmlReader =element.CreateReader()) { System.Diagnostics.Trace.TraceInformation("LoadFromXElement -before des {0}", logCounter++); serializableObject =xmlSerializer.Deserialize(xmlReader) as T; } System.Diagnostics.Trace.TraceInformation("LoadFromXElement afterdes"); return serializableObject; }
最终发现上面加log的两行代码占用了较多时间,通过查阅一些资料发现,XmlSerializer在实例化时会根据其构造函数中的Type参数产生临时的assemblies来进行序列化或者反序列化的工作,从来提高效率,但是如果构造函数选用的不当,就会有内存泄露和性能问题。当使用下面的构造函数时,.NET会重用临时产生的assemblies
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type,String)
但是,如果使用其他的构造函数则会生成同一个临时assembly的多个不同版本,即第一次调用XmlSerializer的构造函数时临时生产一个版本的assemblyA,第二次调用XmlSerializer的构造函数时会生成A的另一个版本,第三次调用XmlSerializer的构造函数时会生成A的第三个版本。。。而之前生成的临时版本还不会被卸载,从而就导致了内存泄露和性能问题
上面的代码使用了XmlSerializer(Type,XmlRootAttribute)构造函数,所以才导致了性能问题
详细说明参见XmlSerializer Class in MSDN,内容摘录如下:
Dynamically GeneratedAssemblies
Toincrease performance, the XML serialization infrastructure dynamically generatesassemblies to serialize and deserialize specified types. The infrastructurefinds and reuses those assemblies. This behavior occurs only when using thefollowing constructors:
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
Ifyou use any of the other constructors, multiple versions of the same assemblyare generated and never unloaded, which results in a memory leak and poorperformance. The easiest solution is to use one of the previously mentioned twoconstructors. Otherwise,
you must cache the assemblies in a
Hashtable
解决办法:
使用Dictionary将第一次实例化的XmlSerializer对象存起来,使用其构造函数的参数作为Key,以后再对同样的Type实例化XmlSerializer时直接从Dictionary中取,改进后的代码
private static readonlyDictionary<string, XmlSerializer> cacheSerializer = newDictionary<string, XmlSerializer>(); public static XmlSerializerGetSerializer(Type type, XmlRootAttribute rootAttr) { var key = string.Format("{0}:{1}",type, rootAttr.ElementName); XmlSerializer serializer; if(!cacheSerializer.TryGetValue(key, out serializer)) { serializer = newXmlSerializer(type, rootAttr); cacheSerializer.Add(key,serializer); } return serializer; }
使用
XmlSerializerxmlSerializer = new XmlSerializer(ObjectType, rootAttr);
// 按照如下方式使用
XmlSerializerxmlSerializer = GetSerializer(ObjectType, rootAttr);
这样就大大提升了性能
参考链接:
http://www.damirscorner.com/XmlSerializerConstructorPerformanceIssues.aspx
http://blogs.msdn.com/b/crm/archive/2009/02/02/boost-performance-with-pre-generated-xmlserializers.aspx
http://mikehadlow.blogspot.com/2006/11/playing-with-xmlserializer.html
Playing with the XmlSerializer
XmlSerializer Performance Issue when SpecifyingXmlRootAttribute
相关文章推荐
- XmlSerializer带来的性能问题及解决办法
- XmlSerializer带来的性能问题及解决办法
- XmlSerializer的GenerateTempAssembly性能问题例外
- Java程序问题 和MySQL 数据库的性能问题解决思路
- ASP.NET设计中的性能优化问题
- [图灵beta]如何解决Oralce的性能问题?
- SQL性能优化之定位网络性能问题的方法(DEMO)
- [转载]DataTable操作中的性能问题
- 构造函数的参数问题
- LoadRunner性能测试问题集锦
- 关于切圆角的性能问题
- 编写高质量代码——谨防因构造函数抛出异常而引发的问题
- NUMA导致的Oracle性能问题
- Linux安装性能问题
- sp_lock诊断Sql Server的性能问题
- slua,ulua性能问题
- 应用数据库典型的三大类性能问题(笔记)
- 禁用生成8.3字符长文件名解决单目录存储大量文件写入性能下降问题
- 【百度分享】频繁分配释放内存导致的性能问题的分析
- 延迟加载解决offset过大导致的分页性能问题