Thursday, September 16, 2010

C# XmlReader vs XDocument vs XmlDocument

Use Xmlreader for parse xml document.
Create an xml file as show below, but with 10000 contact elements called as “address_xw_n.xml” and make it available in D driver (d:\).
<AddressBook>
  <Contact>
    <Name>Person1</Name>
    <Address1><![CDATA[Number101]]></Address1>
    <Address2><![CDATA[Address501]]></Address2>
    <Zip>50001</Zip>
    <Phone><![CDATA[999991]]></Phone>
 </Contact>
</AddressBook>
The below code demonstrate the time take to parse the above created xml file using XmlDocument, XDocument and XmlReader.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Diagnostics;
using System.Xml.Linq;
namespace XmlParse
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch objSW = null;
            String strNormalFilePath;
            strNormalFilePath = @"d:\address_xw_n.xml";
            XmlDocument xmlNDoc;
            XmlReader xmlNReader = null;
            XDocument xNDoc=null;
            objSW = new Stopwatch();

            //xml parsing using XmlDocument - Normal format
            objSW.Reset();
            objSW.Start();
            xmlNDoc = new XmlDocument();
            xmlNDoc.Load(strNormalFilePath);
            XmlElement xmlDocNElem = xmlNDoc.DocumentElement;
            for (int i = 0; i < xmlDocNElem.ChildNodes.Count; i++)
            {
                XmlNode xmlNode = xmlDocNElem.ChildNodes[i];
                for (int j = 0; j < xmlNode.ChildNodes.Count; j++)
                {
                    string strName = xmlNode.ChildNodes[j].Name;
                    string strValue = xmlNode.ChildNodes[j].ChildNodes[0].Value;
                    //Console.WriteLine(strName + "-" + strValue);
                }
            }
            //xmlNDoc = null;
            objSW.Stop();
            Console.WriteLine("XML parsing using XmlDocument - Normal format");
            Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
                objSW.Elapsed.TotalMilliseconds);
            Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
                objSW.ElapsedMilliseconds);

            //xml parsing using XDocument - Normal format
            objSW.Reset();
            objSW.Start();
            xNDoc = XDocument.Parse(xmlNDoc.OuterXml);
            foreach (XElement e in xNDoc.Root.Elements())
            {
                foreach (XElement c in e.Elements())
                {
                    string strName = c.Name.ToString();
                    string strValue = c.Value;
                    //Console.WriteLine(strName+"-"+strValue);
                }
            }
            xNDoc = null;
            objSW.Stop();
            Console.WriteLine("XML parsing using XDocument - Normal format");
            Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
                objSW.Elapsed.TotalMilliseconds);
            Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
                objSW.ElapsedMilliseconds);

            //xml parsing using XmlReader - Normal format
            objSW.Reset();
            objSW.Start();
            using (xmlNReader = XmlReader.Create(strNormalFilePath))
            {
                while (xmlNReader.Read())
                {
                    switch (xmlNReader.NodeType)
                    {
                        case XmlNodeType.Element:
                            {
                                switch (xmlNReader.Name)
                                {
                                    case "Name":
                                    case "Zip":
                                        {
                                            string strName = xmlNReader.Name;
                                            xmlNReader.Read();
                                            string strValue = xmlNReader.Value;
                                            //Console.WriteLine(strName +
                                            //  "-" + strValue);
                                            break;
                                        }
                                    case "Address1":
                                    case "Address2":
                                    case "Phone":
                                        {
                                            string strName = xmlNReader.Name;
                                            xmlNReader.Read();
                                            string strValue = xmlNReader.Value;
                                            //Console.WriteLine(strName +
                                            //  "-" + strValue);
                                            break;
                                        }
                                }

                                break;
                            }
                    }
                }
            }

            objSW.Stop();
            Console.WriteLine("XML parsing using XmlReader - Normal format");
            Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
                objSW.Elapsed.TotalMilliseconds);
            Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
                objSW.ElapsedMilliseconds);
            Console.ReadLine();


        }
    }
}
Output:
XML parsing using XmlDocument - Normal format
TimeElapsed (Stopwatch float):5232.8249ms
TimeElapsed (Stopwatch rounded):5232ms
XML parsing using XDocument - Normal format
TimeElapsed (Stopwatch float):114.9677ms
TimeElapsed (Stopwatch rounded):114ms
XML parsing using XmlReader - Normal format
TimeElapsed (Stopwatch float):42.7921ms
TimeElapsed (Stopwatch rounded):42ms

Note: XmlDocument can be considered, if forward and backward reference is unavoidable during the parsing of xml document.

Rule: Use XmlReader for parsing xml document.

1 comment:

Dileepa Wijayanayake said...

xml doms tend to take 10 times the memory of the size of xml. So the xml fragment is 20 bytes, when it loads into memory it takes 200 bytes. We have tested both xDocument and xmlDocument. xmlDcoument tends to manage memory better and perform. xDocument is easy to code and query but performance and memory usage seems an issue. check out http://www.cDevWorkflow.com