Partager via


Requêtes compilées statiquement (LINQ to XML)

L'un des principaux avantages de LINQ to XML en terme de performance, par rapport à XmlDocument, est que les requêtes dans LINQ to XML sont compilées statiquement, tandis que les requêtes XPath doivent être interprétées lors de l'exécution.Cette fonctionnalité étant intégrée dans LINQ to XML, vous n'avez pas à effectuer d'étapes supplémentaires pour en bénéficier, mais il est utile de comprendre cette distinction pour pouvoir choisir entre ces deux technologies.Cette rubrique explique en quoi consiste la différence.

Requêtes compilées statiquement etXPath

L'exemple suivant montre comment obtenir les éléments descendants avec un nom spécifié et avec un attribut avec une valeur spécifiée.

L'expression XPath équivalente est indiquée ci-dessous :

//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);
Dim po = XDocument.Load("PurchaseOrders.xml")

Dim list1 = From el In po.Descendants("Address")
            Where el.@Type = "Shipping"

For Each el In list1
    Console.WriteLine(el)
Next

L'expression de requête contenue dans cet exemple est réécrite par le compilateur en syntaxe de requête fondée sur une méthode.L'exemple suivant, qui est écrit dans la syntaxe de requête fondée sur une méthode, produit les mêmes résultats que l'exemple précédent :

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);
Dim po = XDocument.Load("PurchaseOrders.xml")

Dim list1 As IEnumerable(Of XElement) = po.Descendants("Address").Where(Function(el) el.@Type = "Shipping")

For Each el In list1
    Console.WriteLine(el)
Next 

La méthode Where est une méthode d'extension.Pour plus d'informations, consultez Méthodes d'extension (Guide de programmation C#).Where étant une méthode d'extension, la requête ci-dessus est compilée comme si elle était écrite comme suit :

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);
Dim po = XDocument.Load("PurchaseOrders.xml")

Dim list1 = Enumerable.Where(po.Descendants("Address"), Function(el) el.@Type = "Shipping")

For Each el In list1
    Console.WriteLine(el)
Next

Cet exemple produit exactement les mêmes résultats que les deux exemples précédents.Ceci illustre le fait que les requêtes sont effectivement compilées en appels de méthodes liés statiquement.Ceci, combiné à la sémantique d'exécution différée des itérateurs, améliore la performance.Pour plus d'informations sur la sémantique d'exécution différée des itérateurs, consultez Exécution et évaluation différées dans LINQ to XML.

Notes

Ces exemples sont représentatifs du code susceptible d'être écrit par le compilateur.L'implémentation réelle peut différer légèrement de ces exemples, mais la performance sera identique ou similaire à celle de ces exemples.

Exécution d'expressions XPath avec XmlDocument

L'exemple suivant utilise XmlDocument pour produire les mêmes résultats que les exemples précédents :

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();
Dim reader = Xml.XmlReader.Create("PurchaseOrders.xml")
Dim doc As New Xml.XmlDocument()
doc.Load(reader)
Dim nl As Xml.XmlNodeList = doc.SelectNodes(".//Address[@Type='Shipping']")
For Each n As Xml.XmlNode In nl
    Console.WriteLine(n.OuterXml)
Next
reader.Close()

Cette requête retourne le même résultat que les exemples qui utilisent LINQ to XML ; la seule différence est que LINQ to XML met en retrait le XML imprimé, tandis que ce n'est pas le cas pour XmlDocument.

Toutefois, l'approche XmlDocument fournit généralement une performance inférieure à LINQ to XML, car la méthode SelectNodes doit effectuer les opérations suivantes au niveau interne chaque fois qu'elle est appelée :

  • Elle analyse la chaîne qui contient l'expression XPath, en scindant la chaîne en jetons.

  • Elle valide les jetons pour s'assurer que l'expression XPath est valide.

  • Elle traduit l'expression en arborescence d'expression interne.

  • Elle effectue l'itération sur les nœuds, en sélectionnant de façon appropriée les nœuds pour le jeu de résultats basé sur l'évaluation de l'expression.

Ces opérations représentent un travail considérablement plus important que celui effectué par la requête LINQ to XML correspondant.La différence de performance spécifique varie selon les différents types de requête, mais en général les requêtes LINQ to XML effectuent moins de tâches et fournissent donc une meilleure performance que l'évaluation des expressions XPath à l'aide de XmlDocument.

Voir aussi

Concepts

Performances (LINQ to XML)