【问题标题】:Best/Fastest way to find values of a element in a xml file在 xml 文件中查找元素值的最佳/最快方法
【发布时间】:2020-11-05 13:38:29
【问题描述】:

我的程序主要做的是搜索 xml 并返回那些在元素中具有特定值的文件名。

我想我必须先向您展示我的 xml,然后才能继续:

 <DocumentElement>
   <Protocol>
     <DateTime>10.03.2003</DateTime>
     <Item>Date</Item>
     <Value />
   </Protocol>
   <Protocol>
     <DateTime>05.11.2020</DateTime>
     <Item>Status</Item>
     <Value>Ok</Value>
   </Protocol>
 </DocumentElement>

我有几千个具有这种精确布局的 xml 文件。用户可以通过以下方法获取所有文件的列表:

public List<string> GetFiles(string itemValue, string element, string value)
{
    return compatibleFiles.Where(path => XmlHasValue(path, itemValue, element, value)).ToList();
}

无论 xml 是否具有所需的值,此方法都会返回:

private bool XmlHasValue(string filePath, string itemValue, string element, string value)
{
    try
    {
        string foundValue = XDocument.Load(filePath)
            .Descendants()
            .Where(el => el.Name == "Item" && el.Value == itemValue)
            .First()
            .Parent
            .Descendants()
            .Where(des => des.Name == element && des.Value == value)
            .First()
            .Value;
         return foundValue == value;
    }
    catch (Exception)
    {
        return false;
    }
}

compatibleFiles 是一个列表,其中包含具有正确布局/格式(上面的 xml 代码)的 xml 文件的所有路径。用户提供GetFiles方法如下:

  • itemValue -> 'Item' 元素应该具有的值,例如“Status”
  • element -> 他要检查的元素的名称(在同一个“协议”元素中),f.E. “值”或“日期”
  • value -> element 元素的值,在我们的示例中为“Ok”

问题是,这些方法需要很长时间才能完成,而且我几乎可以肯定有更好更快的方法来做我想做的事。我不知道GetFiles 是否可以更快,但XmlHasValue 肯定可以。以下是一些测试结果:

你们知道更快的方法吗?真的很有帮助。

更新

原来这一切都只是因为 IO 线程。如果你有同样的问题并且认为你的代码很糟糕,你应该首先检查它是否只是一个使用所有 cpu 功率的线程。

【问题讨论】:

  • 首先使用profiler。如果 99% 的时间是 IO 并且您已经拥有 SSD,那么就没有什么可改进的了。除非你真的想要 19456 毫秒而不是 19546 毫秒。
  • 您是否尝试使用 xpath 查询?示例:XmlNodeList xnList = xml.SelectNodes("/Names/Name");
  • 嗨,斯派克。这个问题和你昨天问的有什么不同? ==> Absolutely fastest way to go through a xml?
  • 如果您只对优化 XML 解析性能感兴趣,则不应使用 XDocument.Load 直接从文件系统加载 XML。先读取字符串变量中带有File.ReadAllText的文件文本,然后使用XDocument.Parse方法解析字符串。这样您就可以对您感兴趣的零件进行准确的测量。

标签: c# xml performance element readxml


【解决方案1】:

正如@Sinatr 提到的那样。在调查性能时,分析应该始终是第一步。

一个合理的猜测是什么需要时间

  1. IO
  2. 解析

可以通过获得更快的磁盘或在 RAM 中缓存结果来改进 IO。如果进行多次搜索,后者可能会大大提高性能,但会引入缓存失效等问题。

根据“What is the best way to parse (big) XML in C# Code”,XmlReader 是解析 xml 的最快方式。 This blog suggest XmlReader is about 2.5 times faster.

如果您有多个文件,您也可以尝试并行处理多个文件。请记住,IO 主要是串行的,因此除非您的 SSD 能够以比文件处理速度更快的速度传输数据,否则您可能无法获得任何收益。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多