问题描述
我的程序的基本作用是搜索xml并返回元素中具有特定值的文件名。
我想我必须先向您展示我的xml,然后才能继续:
qemu-system-aarch64: Property '.acpi' not found
我有数千个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();
}
private bool XmlHasValue(string filePath,string itemValue,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;
}
}
是一个列表,其中包含具有正确布局/格式(上述xml代码)的xml文件的所有路径。用户向compatibleFiles
方法提供以下内容:
-
GetFiles
->“项目”元素应具有的值,例如“状态” -
itemValue
->他要检查的元素名称(在同一“ Protocol”元素中),f.E。 “值”或“日期” -
element
->value
元素的值,在我们的示例中为“确定”
问题在于,这些方法需要很长时间才能完成,而且我几乎可以肯定,有一种更好,更快的方式来完成我想要的事情。我不知道element
是否可以更快地获得,但是GetFiles
肯定可以。这是一些测试结果:
你们知道更快的方法吗?真的很有帮助。
更新
事实证明,这仅仅是因为IO线程。如果您遇到相同的问题,并认为代码不好,则应首先检查它是否只是使用所有cpu功能的线程。
解决方法
就像@Sinatr提到的那样。分析性能始终是调查性能的第一步。
关于需要花费时间的合理猜测
- IO
- 解析
可以通过获取更快的磁盘或在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,否则您可能不会有任何收获。