我有一个基于对象值更新的xml代码。这里的'foreach'循环花了大约12-15分钟来获取一个200 kb的xml文件。请建议我如何提高性能。 (xml文件包含一个四级标记,其中子级(第4级)标记的数量均为10个)
代码:
IEnumerable<XElement> elements = xmlDoc.Descendants();
foreach (DataSource Data in DataLst)
{
XElement xmlElem = (from xmlData in elements
where Data.Name == xmlData.Name.LocalName //Name
&& Data.Store == xmlData.Element(XName.Get("Store", "")).Value
&& Data.Section == xmlData.Element(XName.Get("Section", "")).Value
select xmlData.Element(XName.Get("Val", ""))).Single();
xmlElem.ReplaceWith(new XElement(XName.Get("Val", ""), Data.Value));
}
答案 0 :(得分:2)
这里看起来你有一个O(n)×O(m)问题,因为n = DataList的大小,m = xml的大小。要使这个O(n)+ O(m),你应该索引数据;例如:
var lookup = elements.ToLookup(
x => new {
Name = x.Name.LocalName,
Store = x.Element(XName.Get("Store", "")).Value,
Section = x.Element(XName.Get("Section", "")).Value},
x => x.Element(XName.Get("Val", ""))
);
foreach (DataSource Data in DataLst)
{
XElement xmlElem = lookup[
new {Data.Name, Data.Store, Data.Section}].Single();
xmlElem.ReplaceWith(new XElement(XName.Get("Val", ""), Data.Value));
}
(未经测试 - 仅显示一般方法)
答案 1 :(得分:1)
我认为更好的方法是将XML反序列化为C#类,然后使用LINQ,应该很快。
答案 2 :(得分:0)
如果真的需要很长时间来运行它,那么可能会这样做:
这样,您只需为DataSource中的每个数据迭代一次XML文件。
答案 3 :(得分:0)
目前尚不清楚为什么要花那么长时间 - 这是非常很长时间。 DataLst
中有多少元素?我会尽快重写查询以简化:
IEnumerable<XElement> elements = xmlDoc.Descendants();
foreach (DataSource data in DataLst)
{
XElement valElement = (from element in xmlDoc.Descendants(data.Name)
where data.Store == element.Element("Store").Value
&& data.Section == element.Element("Section").Value
select element.Element("Val")).Single();
valElement.ReplaceWith(new XElement("Val"), data.Value));
}
(顺便说一句,我假设你的元素实际都没有名称空间。)
接下来:考虑替换valElement
的内容,而不是替换元素本身。将其更改为:
valElement.ReplaceAll(data.Value);
现在,这一直都在努力保持避免预计算等的简单性......因为它听起来就好像不应该花这么长时间。但是,可能需要像Marc和Carsten建议的那样构建查找。
答案 4 :(得分:0)
尝试将LINQ中的Single()
调用替换为First()
。
答案 5 :(得分:0)
冒着火焰的危险,你考虑过用XQuery写这个吗?一个体面的XQuery处理器很可能会有一个连接优化器来有效地处理这个查询。
答案 6 :(得分:0)
“非常感谢大家的宝贵时间和精力”
问题答案:实际上,对象'DataLst'的类型为IEnumerable&lt;&gt;花了很多时间来获取值,但在我将其更改为List&lt;&gt;之后键入性能大幅提升(现在在20秒内运行)