哪一个在性能方面是最好的:带XPath的XPathNavigator vs带查询的Linq to Xml
本文关键字:XPathNavigator vs XPath 查询 Xml to Linq 性能 方面 哪一个 | 更新日期: 2023-09-27 18:18:06
我有一个使用XPathNavigator迭代节点的应用程序。
但是我想知道如果我使用LINQ到Xml....
-
我将得到什么好处(性能、可维护性)?
-
使用XPath, LINQ到Xml的性能影响是什么?
我使用c# .net, VS 2010,我的。xml是中等大小。
在前面已经说过的基础上再补充一点,总体性能似乎取决于您实际对相关文档所做的操作。这是我通过比较XElement和XPathNavigator之间解析性能的简单实验得出的结论。
如果您正在选择节点,遍历这些节点并读取一些属性值:
- XElement。元素比XElement.CreateNavigator.Select的速度快近似因子为1.5。
- XElement.CreateNavigator。选择更快XPathNavigator。选择近似因子0.5。
- XPathNavigator。Select比XElement快。XPathSelectElement由因子约为0.5。
另一方面,如果您还读取每个节点的子节点的值,那就有点有趣了:
- XElement。Element比XElement快。XPathSelectElements .
- XElement。XPathSelectElement比XPathNavigator快。选择近似因子为3。
- XPathNavigator。Select比XElement.CreateNavigator.Select快大约0.5倍。
这些结论基于以下代码:
[Test]
public void CompareXPathNavigatorToXPathSelectElement()
{
var max = 100000;
Stopwatch watch = new Stopwatch();
watch.Start();
bool parseChildNodeValues = true;
ParseUsingXPathNavigatorSelect(max, watch, parseChildNodeValues);
ParseUsingXElementElements(watch, max, parseChildNodeValues);
ParseUsingXElementXPathSelect(watch, max, parseChildNodeValues);
ParseUsingXPathNavigatorFromXElement(watch, max, parseChildNodeValues);
}
private static void ParseUsingXPathNavigatorSelect(int max, Stopwatch watch, bool parseChildNodeValues)
{
var document = new XPathDocument(@"data'books.xml");
var navigator = document.CreateNavigator();
for (var i = 0; i < max; i++)
{
var books = navigator.Select("/catalog/book");
while (books.MoveNext())
{
var location = books.Current;
var book = new Book();
book.Id = location.GetAttribute("id", "");
if (!parseChildNodeValues) continue;
book.Title = location.SelectSingleNode("title").Value;
book.Genre = location.SelectSingleNode("genre").Value;
book.Price = location.SelectSingleNode("price").Value;
book.PublishDate = location.SelectSingleNode("publish_date").Value;
book.Author = location.SelectSingleNode("author").Value;
}
}
watch.Stop();
Console.WriteLine("Time using XPathNavigator.Select = " + watch.ElapsedMilliseconds);
}
private static void ParseUsingXElementElements(Stopwatch watch, int max, bool parseChildNodeValues)
{
watch.Restart();
var element = XElement.Load(@"data'books.xml");
for (var i = 0; i < max; i++)
{
var books = element.Elements("book");
foreach (var xElement in books)
{
var book = new Book();
book.Id = xElement.Attribute("id").Value;
if (!parseChildNodeValues) continue;
book.Title = xElement.Element("title").Value;
book.Genre = xElement.Element("genre").Value;
book.Price = xElement.Element("price").Value;
book.PublishDate = xElement.Element("publish_date").Value;
book.Author = xElement.Element("author").Value;
}
}
watch.Stop();
Console.WriteLine("Time using XElement.Elements = " + watch.ElapsedMilliseconds);
}
private static void ParseUsingXElementXPathSelect(Stopwatch watch, int max, bool parseChildNodeValues)
{
XElement element;
watch.Restart();
element = XElement.Load(@"data'books.xml");
for (var i = 0; i < max; i++)
{
var books = element.XPathSelectElements("book");
foreach (var xElement in books)
{
var book = new Book();
book.Id = xElement.Attribute("id").Value;
if (!parseChildNodeValues) continue;
book.Title = xElement.Element("title").Value;
book.Genre = xElement.Element("genre").Value;
book.Price = xElement.Element("price").Value;
book.PublishDate = xElement.Element("publish_date").Value;
book.Author = xElement.Element("author").Value;
}
}
watch.Stop();
Console.WriteLine("Time using XElement.XpathSelectElement = " + watch.ElapsedMilliseconds);
}
private static void ParseUsingXPathNavigatorFromXElement(Stopwatch watch, int max, bool parseChildNodeValues)
{
XElement element;
watch.Restart();
element = XElement.Load(@"data'books.xml");
for (var i = 0; i < max; i++)
{
// now we can use an XPath expression
var books = element.CreateNavigator().Select("book");
while (books.MoveNext())
{
var location = books.Current;
var book = new Book();
book.Id = location.GetAttribute("id", "");
if (!parseChildNodeValues) continue;
book.Title = location.SelectSingleNode("title").Value;
book.Genre = location.SelectSingleNode("genre").Value;
book.Price = location.SelectSingleNode("price").Value;
book.PublishDate = location.SelectSingleNode("publish_date").Value;
book.Author = location.SelectSingleNode("author").Value;
}
}
watch.Stop();
Console.WriteLine("Time using XElement.Createnavigator.Select = " + watch.ElapsedMilliseconds);
}
with books.xml从这里下载
总的来说,看起来XElement解析API(不包括XPath扩展)提供了最好的性能,同时如果文档比较平坦,也更容易使用。如果你有深度嵌套的结构你需要做一些像 这样的事情XElement.Element("book").Element("author").Element("firstname").SomethingElse()
然后XElement。XPathSelectElement可以提供性能和代码可维护性之间的最佳折衷。
嗯,XPathNavigator
通常会比Linq to XML
查询快。但总有"但是"。
Linq to XML
绝对会使你的代码更易读和可维护。阅读linq查询比分析XPath更容易(至少对我来说)。另外,当你写查询的时候,你会得到智能感知,这将有助于使你的代码正确。如果需要的话,Linq to XML
还提供了轻松修改数据的可能性。XPathNavigator
给你只读权限。
另一方面,如果你真的需要顶级性能,XPathNavigator
可能是最好的选择。这完全取决于你当前的情况和你想要实现的目标。如果性能不是问题(XML文件相当小,您不会对该文件发出很多请求,等等),您可以轻松地使用Linq to XML
。否则紧贴XPathNavigator