Je voulais savoir laquelle de ces solutions était la plus performante, et j'ai donc effectué quelques tests comparatifs. Par curiosité, j'ai également comparé les méthodes LINQ à la bonne vieille méthode System.Xml méthode suggérée par Greg. La variation était intéressante et n'était pas ce à quoi je m'attendais, les méthodes les plus lentes étant les suivantes plus de 3 fois plus lent que le plus rapide .
Les résultats sont classés du plus rapide au plus lent :
- CreateReader - Chasseur d'instance (0.113 secondes)
- Plain old System.Xml - Greg Hurlman (0.134 secondes)
- Agrégation avec concaténation de chaînes de caractères - Mike Powell (0.324 secondes)
- StringBuilder - Vin (0.333 secondes)
- String.Join sur tableau - Terry (0.360 secondes)
- String.Concat sur un tableau - Marcin Kosieradzki (0.364)
Méthode
J'ai utilisé un seul document XML comportant 20 nœuds identiques (appelés "hint") :
<hint>
<strong>Thinking of using a fake address?</strong>
<br />
Please don't. If we can't verify your address we might just
have to reject your application.
</hint>
Les chiffres indiqués en secondes ci-dessus sont le résultat de l'extraction du "XML interne" des 20 nœuds, 1000 fois de suite, et de la moyenne de 5 exécutions. Je n'ai pas inclus le temps nécessaire pour charger et analyser le XML dans un fichier de type XmlDocument
(pour le System.Xml ) ou XDocument
(pour tous les autres).
Les algorithmes LINQ que j'ai utilisés sont : (C# - tous prennent un XElement
"parent" et renvoie la chaîne XML interne)
Créer un lecteur :
var reader = parent.CreateReader();
reader.MoveToContent();
return reader.ReadInnerXml();
Agrégation avec concaténation de chaînes de caractères :
return parent.Nodes().Aggregate("", (b, node) => b += node.ToString());
StringBuilder :
StringBuilder sb = new StringBuilder();
foreach(var node in parent.Nodes()) {
sb.Append(node.ToString());
}
return sb.ToString();
String.Join sur le tableau :
return String.Join("", parent.Nodes().Select(x => x.ToString()).ToArray());
String.Concat sur le tableau :
return String.Concat(parent.Nodes().Select(x => x.ToString()).ToArray());
Je n'ai pas montré l'algorithme "Plain old System.Xml" ici, car il s'agit simplement d'appeler .InnerXml sur les nœuds.
Conclusion
Si les performances sont importantes (par exemple, beaucoup d'XML, analysé fréquemment), je voudrais d'utiliser la méthode de Daniel CreateReader
chaque fois que la méthode . Si vous n'effectuez que quelques requêtes, il est préférable d'utiliser la méthode Aggregate de Mike, plus concise.
Si vous utilisez XML sur de grands éléments avec beaucoup de nœuds (peut-être des centaines), vous commencerez probablement à voir l'avantage d'utiliser StringBuilder
par rapport à la méthode de l'agrégat, mais pas par rapport à la méthode de l'eau. CreateReader
. Je ne pense pas que le Join
y Concat
ne seraient jamais plus efficaces dans ces conditions, en raison de la pénalité liée à la conversion d'une grande liste en un grand tableau (même évidente ici avec des listes plus petites).