What is best for performance: XPathNavigator with XPath vs Linq in Xml with query?

I have an application in which I use XPathNavigator to iterate over nodes. It is working fine.

But I want to know that if I use LINQ for Xml ....

  • What benefits (performance, maintainability) will I get?

  • With XPath, LINQ to Xml, what is performance?

I am using C # .net, VS 2010 and my .xml is medium size.

+4
source share
2 answers

Well, XPathNavigator will usually be faster than Linq to XML queries. But there is always a but.

Linq to XML will certainly make your code more readable and maintainable. It’s easier for me (at least for me) to read the linq query and then parse the XPath. In addition, you will get intellisense when writing a query that will help make your code correct. Linq to XML also gives you the ability to easily modify data if necessary. XPathNavigator provides read-only access.

On the other hand, if you really need maximum performance, XPathNavigator is probably the way to go. It just depends on your current scenario and what you are trying to execute. If performance is not a problem (the XML file is quite small, you won’t make many requests for this file, etc.), you can easily switch from Linq to XML . Otherwise, stick to the XPathNavigator button.

+3
source

To add to what has already been said here, overall performance seems to depend on what you are actually doing with the document in question. This is what I did based on a simple experimental run comparing the parsing performance between XElement and XPathNavigator.

If you select nodes, bypass these nodes and read some attribute values:

  • XElement.Element is faster than XElement.CreateNavigator.Select with an approximate ratio of 1.5.
  • XElement.CreateNavigator.Select is faster than XPathNavigator. Choose an approximate factor of 0.5.
  • XPathNavigator.Select is faster than XElement.XPathSelectElement by an approximate factor of 0.5.

On the other hand, if you also read the meaning of each of the node children, it becomes a little interesting:

  • XElement.Element is faster than XElement.XPathSelectElements with an approximate coefficient of 0.5.
  • XElement.XPathSelectElement is faster than XPathNavigator. Select an approximate factor of 3.
  • XPathNavigator.Select is faster than XElement.CreateNavigator.Select by about 0.5.

These findings are based on the following code:

  [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 downloaded from here

All in all, it seems that the XElement analysis API, excluding XPath extensions, gives you better performance and is also easier to use if your document is somewhat flat. If you have deep nested structures where you need to do something like

 XElement.Element("book").Element("author").Element("firstname").SomethingElse() 

then XElement.XPathSelectElement can provide a better compromise between performance and code support.

+5
source

Source: https://habr.com/ru/post/1386646/


All Articles