LINQ to XML and LINQ to XML with XPath performance review

by Arnold Matusz 4 12 2008

In my post about LINQ to XML - XPath I've mentioned how Microsoft warns about the performance bottleneck when using LINQ to XML with the Extension class from the System.Linq.XPath namespace.

"There is some performance penalty for using these methods. Using LINQ to XML queries yields better performance. So it is only advisable to use such LINQ to XML with XPath queries if and only if your application won't suffer from the slight loss of performance!"

This is very nice to know ... but which is the point when you shouldn't use it. Where is the point where you say something is under a specific benchmark? How slow does it need to be so we don't consider LINQ to XML with XPath anymore.

In order to test this I searched for a big enough dataset. I've found it exporting the SalesOrderDetail table from the AdventureWorks database which you can get at: www.codeplex.com/MSFTDBProdSamples. The previously mentioned table contains more than 120000 rows which exported to an xml file weighs more than 54MB's. This should be well enough for a performance test.

First of all I need to mention that the actual loading into memory of the records takes around 6-7 seconds. But by querying the datasource for the same data with the different procedures yields different time results indeed.

As a short description I'll explain that I've made 3 different queries with the same name (RunQuery1(), RunQuery2(), RunQuery3()) for both LINQ to XML and LINQ to XML using XPath. I've launched a Performance Profiling Session set to Instrumentation in Visual Studio 2008 Team System (this is where I receive the actual measurements).

LINQ to XML: 246.96 ms

/// <summary>
/// Count how many items the Order (with id = 46348) contains 
/// </summary>
/// <param name="xDoc">A loaded XDocument</param>
/// <returns>The number of distinct OrderDetailItems in an Order</returns>
public static int RunQuery1(XDocument xDoc)
{
    IEnumerable<XElement> elements =
        from result in xDoc.Descendants("dataroot").Descendants("SalesOrderDetail")
        where result.Element("SalesOrderID").Value == "46348"
        select result;
    return elements.Count();
}

LINQ to XML with XPath: 1025.95 ms

public static int RunQuery1(XDocument xDoc)
{
    return xDoc.XPathSelectElements("//dataroot/SalesOrderDetail[SalesOrderID=46348]").Count();
}

Immediately we can see the performance loss on the XPath query, let's see how the rest get on.

LINQ to XML: 208.88 ms

/// <summary>
/// Count all the SalesOrderDetail items: where the ordered quantity is > 2 for a ProductID
/// </summary>
/// <param name="xDoc">A loaded XDocument</param>
/// <returns>The number of OrderDetail items where more than 2 ProductID's were ordered</returns>
public static int RunQuery2(XDocument xDoc)
{
    IEnumerable<XElement> elements =
        from result in xDoc.Descendants("dataroot").Descendants("SalesOrderDetail")
        where String.CompareOrdinal(result.Element("OrderQty").Value, "2") > 0
              && result.Element("ProductID").Value == "761"
        select result;

    return elements.Count();
}

LINQ to XML with XPath: 1013.19 ms

public static int RunQuery2(XDocument xDoc)
{
    return xDoc.XPathSelectElements("//dataroot/SalesOrderDetail[OrderQty>2 and ProductID=761]").Count();
}

LINQ to XML: 218.37 ms

/// <summary>
/// Count all the SalesOrderDetails items: where the the line total is more than $4000
/// </summary>
/// <param name="xDoc">A loaded XDocument</param>
/// <returns>Number of OrderDetail Items where the LineTotal is above $4000</returns>
public static int RunQuery3(XDocument xDoc)
{
    IEnumerable<XElement> elements =
        from result in xDoc.Descendants("dataroot").Descendants("SalesOrderDetail")
        where String.CompareOrdinal(result.Element("LineTotal").Value, "4000.00") > 0
        select result;

    return elements.Count();
}

LINQ to XML with XPath: 944.9 ms

public static int RunQuery3(XDocument xDoc)
{
    return xDoc.XPathSelectElements("//dataroot/SalesOrderDetail[LineTotal>4000.00]").Count();
}

LINQ to XML Performance

It is absolutely clear how inefficient the XPath solution is compared to the normal LINQ to XML approach. In most cases running an XPath query will result in a 5 times longer execution period than querying using standard LINQ to XML.

Why you should still use XPath then?

  • it's easy to read
  • thus easy to maintain
  • and considering my 120000 dataset a 1s delay isn't that critical - in case your application needs some super lightning fast response. If you need to use  a small <10KB file performance difference aren't noticeable.

Why you should also consider LINQ to XML?

  • fast
  • sql like syntax and behaviour
  • allows grouping (for example SalesOrderID, to compute the total for the order)
  • allows aggregation (sum, avg, etc.)

From here it's anybody's chose and guess. Feel free to use both approaches as there is no right and wrong one, there's only the right one (but for a very specific purpose only).

DZone it Digg it Submit to StumbleUpon Submit to Technorati Submit to reddit.com Submit to del.icio.us Submit to NewsVine Submit to Furl Submit to BlinkList

Tags: ,

.NET 3.5 SP1 | ASP.NET | C# | LINQ | Programming

Comments

12/5/2008 12:33:00 AM #

trackback

Trackback from DotNetKicks.com

LINQ to XML and LINQ to XML with XPath performance review

DotNetKicks.com |

12/12/2008 5:42:56 PM #

Jarrett

Great post.  I love to see the metrics.  However, it does appear that the XLinq is not functionally equivalent to the XPath in your examples.  The XLinq is comparing strings and the XPath is comparing numbers.  For the XPath to be equivalent you'd need to surround the numbers in single quotes.
For example:

//dataroot/SalesOrderDetail[OrderQty &gt; '2' and ProductID = '761']

I doubt it changes the metrics much.

Jarrett |

12/17/2008 6:41:07 PM #

Arnold Matusz

Hello Jarret

Thanks for your suggestion! I'll do another test like that, but as far as I remember I've done loads of tests with different comparisons and the difference in time was always somehow constant, I.E.: LINQ to XML being 5 times faster than LINQ To XML using XPath.

Thanks again and kind regards!

Arnold Matusz Romania |

1/11/2009 8:33:29 AM #

trackback

Trackback from Web Development Community

LINQ to XML and LINQ to XML with XPath performance review

Web Development Community |