Jun 04

Vamos comparar performance manipulando XML no Framework .NET 4.0. Comparação entre XmlDocument, XPathDocument, XDocument e XmlReader.

Segue código de teste. (lembre que devem ser usados CTRL+F5 e config de RELEASE para se executar quaisquer testes que simulem perfomance em ambiente de produção)

using System;

using System.Diagnostics;

using System.IO;

using System.Threading;

using System.Xml;

using System.Xml.Linq;

using System.Xml.XPath;

namespace XmlPerformance

{

    class Program

    {

        static FileInfo _xmlFile;

        //static Stream _stream;         

        static void Main(string[] args)

        {

            Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(2);

            // Uses the second Core or Processor for the Test            

            Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;

            // Prevents "Normal" processes from interrupting Threads            

            Thread.CurrentThread.Priority = ThreadPriority.Highest;

            // Prevents "Normal" Threads from interrupting this thread             

            _xmlFile = new FileInfo(@"C:\file.xml");

            //_stream = File.OpenRead(@"C:\file.xml");             

            Console.WriteLine();

            Console.WriteLine();

            Console.WriteLine("Warmup");

            var stopWatch = new Stopwatch();

 

            stopWatch.Start();

            while (stopWatch.ElapsedMilliseconds < 1200)

            // A Warmup of 1000-1500 mS             

            // stabilizes the CPU cache and pipeline.            

            {

                WarmUp(TestXmlDocument);

                WarmUp(TestXpath);

                WarmUp(TestXDocument);

                WarmUp(TestXmlReader);

            } stopWatch.Stop();

            for (int i = 0; i < 5; i++)

            {

                Console.WriteLine();

                Console.WriteLine("Test set " + i);

                Console.WriteLine();

                RunTest("Testing XmlDocument...", TestXmlDocument);

                RunTest("Testing Xpath...", TestXpath);

                RunTest("Testing XDocument...", TestXDocument);

                RunTest("Testing XmlReader...", TestXmlReader);

                Console.WriteLine();

            }

            Console.ReadKey();

        }

        private static void TestXmlDocument()

        {

            var dom = new XmlDocument(); dom.Load(_xmlFile.FullName);

            int i = dom.SelectNodes("//*").Count;

        }

        private static void TestXDocument()

        {

            int i = 0;

            XDocument doc = XDocument.Load(_xmlFile.FullName);

            //i = doc.Descendants().Count();             

            var xElements = doc.Descendants();

            foreach (XElement e in xElements) i++;

        }

        private static void TestXmlReader()

        {

            int i = 0;

            XmlReader rdr = XmlReader.Create(_xmlFile.FullName);

            while (!rdr.EOF) { rdr.Read(); if (rdr.NodeType == XmlNodeType.Element)                     i++; }

        }          private static void TestXpath() { var doc = new XPathDocument(_xmlFile.FullName); int i = doc.CreateNavigator().Select("//*").Count; }          private static void RunTest(string header, TestMethod testMethod) { var stopWatch = new Stopwatch(); if (header != null)                 Console.WriteLine(header); stopWatch.Start(); testMethod(); stopWatch.Stop(); if (header != null) { Console.WriteLine("Executed in {0} ticks", stopWatch.ElapsedTicks); Console.WriteLine(); } }          private static void WarmUp(TestMethod testMethod) { RunTest(header: null, testMethod: testMethod); }

        delegate void TestMethod();

    }

}

 

Segue tela de resultados apresentados na minha máquina e com o xml anexado.

 

 

Config da minha máquina:

 

Xml utilizado para teste:

file - XmlComplexo.xml (402,51 kb)

 

Outro xml, mais simples, que pode ser usado pra teste:

 file - XmlSimples.xml (7,13 kb)

 

Conclusão

Use XDocument, pois o código fica mais limpo e fácil de dar manutenção do que o XmlReader, que é o mais aconselhado caso a performance seja crucial. XmlDocument e XPathDocument nem pensar!!!