XmlDocument vs XElement Performance

I have been using XElement class a lot lately, I was doing some performance tests on this to figure out the difference between this and XmlDocument class and here is what I found.

First of all XElement class is part of .NET Framework 3.5, it was introduced with XML to Linq and is part of System.Xml.Linq namespace. This class has been totally written from scratch to get better usability with LINQ. XElement.Nodes and XElement.Attribtues return IEnumerable which could be easily used to traverse nodes. You can also use them Lambda expressions. For more information on XML to LINQ check https://msdn.microsoft.com/en-us/library/bb387098.aspx.

In my case, I have created a test bench (console application) with two static methods, one uses XMLDocument and the other uses XElement to generate XML. The test case is very simple, iterate through the System assembly exported type, construct a giant XML and save it to a stream. Here is the code for both of the static methods.

    1: //Generates XML using XmlDocument
    2: internal static void GenerateXmlUsingXmlDocument() 
    3: {
    4:     MemoryStream ms =new MemoryStream();
    5:     XmlDocument xmlDoc = new XmlDocument();
    6:     xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", "no"));
    7:     XmlElement assembliesNode = xmlDoc.CreateElement("Assemblies");
    8:     foreach (Type t in Assembly.GetAssembly(typeof(Object)).GetExportedTypes())
    9:     {
   10:         XmlElement assemblyNode = xmlDoc.CreateElement("Assembly");
   11:         XmlAttribute fullTypeName = xmlDoc.CreateAttribute("FullTypeName");
   12:         fullTypeName.Value = t.ToString();
   13:         XmlAttribute isInterfaceName = xmlDoc.CreateAttribute("IsInterface");
   14:         isInterfaceName.Value = t.IsInterface.ToString();
   15:         assemblyNode.Attributes.Append(fullTypeName);
   16:         assemblyNode.Attributes.Append(isInterfaceName);
   17:         assembliesNode.AppendChild(assemblyNode);
   18:     }
   19:     xmlDoc.AppendChild(assembliesNode);
   20:     xmlDoc.WriteContentTo(new XmlTextWriter(ms,System.Text.ASCIIEncoding.ASCII));
   21: }
   22:  
   23: //Generates XML using XElement
   24: internal static void GenerateXmlUsingXElement()
   25: {
   26:     MemoryStream ms = new MemoryStream();
   27:     XElement assembliesNode = new XElement("Assemblies",
   28:             from Type t in Assembly.GetAssembly(typeof(Object)).GetExportedTypes()
   29:             select new XElement("Assembly",
   30:                 new XAttribute("FullTypeName", t.ToString()),
   31:                 new XAttribute("IsInterface", t.IsInterface.ToString())));
   32:     
   33:     assembliesNode.Save(new XmlTextWriter(ms, System.Text.ASCIIEncoding.ASCII));
   34: }

If you look at the above code, the XElement code is small and uses LINQ expressions for generating XML. By using the following code, I repeatedly test the amount of time it takes for each method to execute.

    1: Stopwatch sw = new Stopwatch();
    2: for (int index = 0; index < 51; index++)
    3: {
    4:     sw.Reset(); sw.Start();
    5:     Program.GenerateXmlUsingXmlDocument();
    6:     sw.Stop();
    7:     Console.Write("Generation time using XmlDocument " +
    8:         "and XElement: " + sw.ElapsedMilliseconds);
    9:     sw.Reset(); sw.Start();
   10:     Program.GenerateXmlUsingXElement();
   11:     sw.Stop();
   12:     Console.WriteLine(" : " + sw.ElapsedMilliseconds);
   13:     //Forcing the Garbage Collector to run to make sure,
   14:     //We dispose of all the types we created on the
   15:     //Managed heap.
   16:     GC.Collect();
   17: }
   18: Console.ReadKey();

From the above code, you can see that I am testing each method for 50 times. Additionally, after each test, I explicitly call Garbage Collector to clean up objects created by two methods. Now Here is the screen shot of the output.

XmlDocumentXElement

You can see very clearly, the huge difference in the time it takes to create XML. The difference seems to vary from 6x to 10x times. Specially, this is very important in ASP.NET applications and Web Services where every millisecond counts. One more thing to note that XElement is part of System.Xml.Linq.dll which is part of .NET Framework 3.5, but still uses .NET 2.0 CLR, thus technically you can use a local copy of System.Xml.Linq.dll within your application in cases where you are missing .NET 3.5. But, you will loose all goodness of updations and service packs by the .NET team.

Thanks

Anil RV

Comments

  • Anonymous
    October 08, 2008
    PingBack from http://www.easycoded.com/xmldocument-vs-xelement-performance/
  • Anonymous
    October 08, 2008
    .NET Richmond Code Camp 2008.2 - Functional C# Recap ASP.NET MVC with NHaml - F# Edition Formatting strings
  • Anonymous
    October 08, 2008
    .NET RichmondCodeCamp2008.2-FunctionalC#RecapASP.NETMVCwithNHaml-F#EditionForm...
  • Anonymous
    October 10, 2008
    A comparison with XPathDocument on reads would also be interesting. One thing I can tell you for sure is that XPathDocument will still beat anything else on queries involving preceding/following/preceding-sibling/following-sibling axes (or their XLINQ analogs).
  • Anonymous
    October 10, 2008
    我已经使用XElement有一段时间了,下面我做了一些性能的测试,并指出在xmlDocuemnt和xelement之间的不同。 首先,XElement是.NETFramework3.5的一部分,...
  • Anonymous
    October 13, 2008
    As far as I know, the license that comes with .NET 3.5  does not allow deployment of individual dlls. You must install .NET 3.5 on your servers.
  • Anonymous
    December 08, 2013
    This is an old blog post by now, but you really should GC between the runs of XmlDocument and XDocument, try switching their order switching the order and see what happens :)XDocument is a tad faster, but more of 10% faster than XmlDocument, so no huge difference at all.
  • Anonymous
    April 19, 2015
    >> you will loose all goodness of updations "lose"