C# 使用DataContractSerializer过滤大量XmlNodes非常慢

C# 使用DataContractSerializer过滤大量XmlNodes非常慢,c#,xml,performance,datacontractserializer,C#,Xml,Performance,Datacontractserializer,考虑到下面的代码 List<CustomConversionData> Filter(XmlNodeList nodeList) { var filteredResults= new List<CustomConversionData>(); //Deserailze the data: foreach (XmlNode item in nodeList) { try { CustomConversi

考虑到下面的代码

List<CustomConversionData> Filter(XmlNodeList nodeList)
{
    var filteredResults= new List<CustomConversionData>();
    //Deserailze the data:
    foreach (XmlNode item in nodeList)
    {
      try
      {
        CustomConversionData obj = Deserialize<CustomConversionData>(item.ParentNode.OuterXml);
        filteredResults.Add(obj);

      }
      catch
      {
          try
          {                                            
              CustomConversionData obj = Deserialize<CustomConversionData>(item.OuterXml);
              filteredResults.Add(obj);
          }
          catch (Exception e) {
          }
        }
    }
   return filteredResults;
}
列表筛选器(XmlNodeList nodeList)
{
var filteredResults=新列表();
//对数据进行反序列化:
foreach(节点列表中的XmlNode项)
{
尝试
{
CustomConversionData obj=反序列化(item.ParentNode.OuterXml);
过滤结果添加(obj);
}
抓住
{
尝试
{                                            
CustomConversionData obj=反序列化(item.OuterXml);
过滤结果添加(obj);
}
捕获(例外e){
}
}
}
返回筛选结果;
}
以及进行反序列化的方法

public T Deserialize<T>(string rawXml)
{
    using (XmlReader reader = XmlReader.Create(new StringReader(rawXml)))
    {
        DataContractSerializer formatter =
            new DataContractSerializer(typeof(T));
        return (T)formatter.ReadObject(reader);
    }
}
public T反序列化(字符串rawXml)
{
使用(XmlReader=XmlReader.Create(新的StringReader(rawXml)))
{
DataContractSerializer格式化程序=
新的DataContractSerializer(typeof(T));
return(T)formatter.ReadObject(reader);
}
}
当我为包含8000个节点的
nodeList
运行此操作时,大约需要6个小时。我一直在寻找一种方法来缩短这段时间,一开始我想也许我可以为每个迭代创建一个任务,但是它变得比以前慢了,我认为这是因为在任务之间切换的开销


我想知道提高这段代码性能的最佳方法是什么,因为它似乎非常占用CPU和内存?

在您的
反序列化方法中,我会将
格式化程序
设置为静态成员,因为它每次都是相同的(我不确定它是否在内部缓存)。然后使用
.ReadObject(新的StringReader(rawXml))
来减少引入
XmlReader
所增加的复杂性

然后就变得棘手了。尽量不要使用异常处理来控制逻辑,所以先做一些其他检查,而不是让它抛出并捕获它

最后,我认为最大的胜利将不是采用
XmlNodeList
,而是采用
并创建
XmlReader
来扫描XML,并在需要时仅对其进行反序列化。拥有所有这些对象图的前期成本将迅速增加

编辑:另一个建议是,将签名更改为
IEnumerable
yield return
,您可以在此处执行
。添加(…)
,这样消耗代码就可以流式显示结果,从而降低峰值内存使用率


Edit2:每次都先选择
ParentNode
,我觉得很奇怪。如果
XmlNodeList
来自
.ChildNodes
调用,那么您将反复反序列化相同的内容。如果它来自
SelectNodes(“…”)
,那么您可能会更聪明地选择正确的节点,首先使用XPath,而不必获取父节点。如果仍然需要这样做,请在此处创建一个
XmlReader
,检查元素名称,然后根据该名称确定是否需要父元素。如果您有正确的元素,那么您可以将
XmlReader
传递到
Derserialize
,保存另一个副本。

我需要查看带有重复主标记的xml的几个部分。对于这样一个小文件来说,6个小时真是太长了。谢谢你,斯图尔特,我实际上进一步细分了
节点列表
,其中包含8000个节点,分为50个块,并同时处理它们,从而将时间从6小时减少到7分钟。我会采纳你的建议,因为目前我可以看出,通过使用TPL,CPU和内存的使用率相当高,需要进一步改进。斯图尔特,
。ReadObject
不接受
StringReader
,因此我不能使用
。ReadObject(新StringReader(rawXml))