Consultas compiladas de forma estática [LINQ to XML]

Actualización: November 2007

Una de las ventajas de rendimiento más importantes de LINQ to XML, a diferencia de XmlDocument, es que las consultas de LINQ to XML se compilan estáticamente, mientras que las consultas XPath deben interpretarse durante la ejecución. Esta característica está incorporada en LINQ to XML, de modo que no tiene que efectuar pasos adicionales para aprovecharla, pero resulta útil comprender la distinción a la hora de elegir entre las dos tecnologías. Este tema explica la diferencia.

Consultas compiladas de forma estática frente a XPath

En el ejemplo siguiente se muestra cómo obtener los elementos descendientes con un nombre especificado y con un atributo con un valor especificado.

A continuación figura la expresión XPath equivalente:

.//Address[@Type='Shipping']
XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
    from el in po.Descendants("Address")
    where (string)el.Attribute("Type") == "Shipping"
    select el;

foreach (XElement el in list1)
    Console.WriteLine(el);

El compilador reescribe la expresión de consulta de este ejemplo con la sintaxis de consulta basada en métodos. En el ejemplo siguiente, que está escrito en la sintaxis de consulta basada en métodos, se producen los mismos resultados que en el anterior:

XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
    po
    .Descendants("Address")
    .Where(el => (string)el.Attribute("Type") == "Shipping");

foreach (XElement el in list1)
    Console.WriteLine(el);

El método Where es una extensión del método. Para obtener más información, vea Métodos de extensión (Guía de programación de C#). Dado que Where es un método de extensión, la consulta anterior se compila como si estuviera escrita como se muestra a continuación:

XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
    System.Linq.Enumerable.Where(
        po.Descendants("Address"),
        el => (string)el.Attribute("Type") == "Shipping");

foreach (XElement el in list1)
    Console.WriteLine(el);

Este ejemplo produce exactamente los mismos resultados que los dos ejemplos anteriores. Esto ilustra el hecho de que las consultas se compilan de forma efectiva en llamadas a método vinculadas estáticamente. Esto, combinado con la semántica de ejecución aplazada de los iteradores, mejora el rendimiento. Para obtener más información sobre la semántica de ejecución aplazada de los iteradores, vea Ejecución aplazada y evaluación diferida en LINQ to XML.

Nota:

Estos ejemplos son representativos del código que el compilador podría escribir. La implementación real podría diferir ligeramente de estos ejemplos, pero el rendimiento será el mismo o similar a estos ejemplos.

Ejecutar expresiones XPath con XmlDocument

En el ejemplo de código siguiente se usa XmlDocument para lograr los mismos resultados que en los ejemplos anteriores:

XmlReader reader = XmlReader.Create("PurchaseOrders.xml");
XmlDocument doc = new XmlDocument();
doc.Load(reader);
XmlNodeList nl = doc.SelectNodes(".//Address[@Type='Shipping']");
foreach (XmlNode n in nl)
    Console.WriteLine(n.OuterXml);
reader.Close();

Esta consulta devuelve el mismo resultado que los ejemplos que usan LINQ to XML; la única diferencia es que LINQ to XML aplica sangría al XML impreso, mientras que XmlDocument no.

No obstante, el enfoque de XmlDocument generalmente no funciona tan bien como LINQ to XML, porque el método SelectNodes debe realizar lo siguiente internamente cada vez que se le llama:

  • Analiza la cadena que contiene la expresión XPath, y divide la cadena en tokens.

  • Valida los tokens para asegurarse de que la expresión XPath es válida.

  • Traduce la expresión a un árbol de expresión interno.

  • Recorre en iteración los nodos, y selecciona de forma adecuada los nodos del conjunto de resultados basándose en la evaluación de la expresión.

Esto es bastante más que el trabajo realizado por la consulta LINQ to XML correspondiente. La diferencia de rendimiento específica varía para distintos tipos de consultas, pero en general las consultas LINQ to XML efectúan menos operaciones y, por lo tanto, se ejecutan mejor, que si se evalúan las expresiones XPath con XmlDocument.

Vea también

Conceptos

Rendimiento (LINQ to XML)