哪个性能最好:带XPath的XPathNavigator vs带查询的Linq to Xml?
我有一个应用程序,使用XPathNavigator来迭代节点。它工作正常。哪个性能最好:带XPath的XPathNavigator vs带查询的Linq to Xml?
但我想知道,如果我使用LINQ到XML ....
什么好处(性能,可维护性),我会得到什么?
用XPath,LINQ to Xml是什么性能打击?
我使用C#.net,VS 2010和我的.xml是中等大小。
那么,XPathNavigator
通常会快于Linq to XML
查询。但总是有'但'。
Linq to XML
肯定会让你的代码更具可读性和可维护性。阅读linq查询然后分析XPath会更容易(至少对我来说)。另外 - 在写查询时你会得到智能感知,这将有助于使你的代码正确。 Linq to XML
也为您提供了轻松修改数据的可能性,如果这是您的需要。 XPathNavigator
为您提供只读访问权限。
另一方面,如果您确实需要顶级性能,XPathNavigator
可能是最佳选择。它仅取决于您当前的场景以及您想要完成的内容。如果性能不是问题(XML文件相当小,您不会向这个文件发出很多请求等),您可以轻松地使用Linq to XML
。否则坚持接近XPathNavigator
。
为了增加已经在此处陈述的内容,整体表现似乎取决于您对相关文档的实际操作。这是我基于一个简单的实验运行得出的结论,比较了XElement与XPathNavigator之间的解析性能。
如果您选择的节点,遍历这些节点和阅读一些属性值:
- XElement.Element是1.5的 近似系数比XElement.CreateNavigator.Select更快。
- XElement.CreateNavigator.Select比XPathNavigator更快 。选择近似系数0.5。
- XPathNavigator.Select比XElement.XPathSelectElement快 约为0.5。
在另一方面,如果你还读每个节点的孩子们的价值就有点耐人寻味:
- XElement.Element是0.5的近似系数比XElement.XPathSelectElements更快。
- XElement.XPathSelectElement是由3
- 近似因子XPathNavigator.Select是由0.5的近似因数大于XElement.CreateNavigator.Select速度比XPathNavigator.Select快。
这些结论是基于以下代码:
[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);
}
用的books.xml从here
总体下载,它看起来像的XElement解析API,不包括XPath的扩展,使您最好的性能,同时也更容易使用,如果你的文档有点平淡。如果你有,你必须做一些像
XElement.Element("book").Element("author").Element("firstname").SomethingElse()
深嵌套结构则XElement.XPathSelectElement可以提供性能和代码的可维护性之间的最佳平衡。
你有没有考虑测量? – 2011-12-16 06:08:27
@MitchWheat不,我需要将我的代码从XPathNavigator更改为LINQ到xml。所以在做这件事之前,我想知道它 – Syed 2011-12-16 06:11:52