Best/Fastest 在 xml 文件中查找元素值的方法

Best/Fastest way to find values of a element in a xml file

我的程序主要做的是搜索 xml 和 returns 元素中具有特定值的文件名。

我想我必须先给你看我的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();
}

并且此方法 returns 无论 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 文件的所有路径,这些文件具有正确的 layout/format(上面的 xml 代码)。用户提供 GetFiles 方法如下:

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

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

更新

原来都是IO线程的问题。如果你有同样的问题并认为你的代码不好,你应该首先检查它是否只是一个使用所有 cpu power 的线程。

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

关于什么需要时间的合理猜测是

  1. IO
  2. 正在解析

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

等问题

根据“What is the best way to parse (big) XML in C# Code" XmlReader is the fastest way to parse xml. This blog suggest XmlReader is about 2.5 times faster.

如果您有多个文件,您也可以尝试并行处理多个文件。请记住,IO 主要是串行的,因此除非您拥有可以比文件处理速度更快地传输数据的 SSD,否则您可能什么也得不到。