Chciałem sprawdzić, które z tych sugerowanych rozwiązań działa najlepiej, więc przeprowadziłem kilka testów porównawczych. W interesie porównałem również metody LINQ ze zwykłą starą metodą System.Xml sugerowaną przez Grega. Odmiana była interesująca i nie tego się spodziewałem, przy czym najwolniejsze metody były ponad 3 razy wolniejsze niż najszybsze .
Wyniki uporządkowane według najszybszego do najwolniejszego:
- CreateReader - łowca instancji (0,113 sekundy)
- Zwykły stary System.Xml - Greg Hurlman (0,134 sekundy)
- Agregowanie z konkatenacją ciągów - Mike Powell (0,324 sekundy)
- StringBuilder - Vin (0,333 sekundy)
- String.Join on array - Terry (0,360 sekundy)
- String.Concat na tablicy - Marcin Kosieradzki (0.364)
metoda
Użyłem pojedynczego dokumentu XML z 20 identycznymi węzłami (zwanymi „wskazówką”):
<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>
Liczby pokazane powyżej w sekundach są wynikiem wyodrębnienia „wewnętrznego kodu XML” 20 węzłów 1000 razy z rzędu i obliczenia średniej (średniej) z 5 przebiegów. Nie uwzględniłem czasu potrzebnego na załadowanie i przeanalizowanie XML do postaci XmlDocument(dla metody System.Xml ) lub XDocument(dla wszystkich pozostałych).
Użyte przeze mnie algorytmy LINQ to: (C # - wszystkie pobierają XElement„rodzica” i zwracają wewnętrzny ciąg XML)
CreateReader:
var reader = parent.CreateReader();
reader.MoveToContent();
return reader.ReadInnerXml();
Agreguj z konkatenacją ciągów:
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 on array:
return String.Join("", parent.Nodes().Select(x => x.ToString()).ToArray());
String.Concat na tablicy:
return String.Concat(parent.Nodes().Select(x => x.ToString()).ToArray());
Nie pokazałem tutaj algorytmu "Zwykły stary System.Xml", ponieważ po prostu wywołuje .InnerXml na węzłach.
Wniosek
Jeśli ważna jest wydajność (np. Dużo XML, często parsowany), za CreateReaderkażdym razem używałbym metody Daniela . Jeśli robisz tylko kilka zapytań, możesz użyć bardziej zwięzłej metody Aggregate Mike'a.
Jeśli używasz XML na dużych elementach z dużą liczbą węzłów (może 100), prawdopodobnie zaczniesz dostrzegać korzyści płynące z używania StringBuildermetody Aggregate, ale nie ponad CreateReader. Nie sądzę, aby metody Joini Concatbyły kiedykolwiek bardziej wydajne w tych warunkach ze względu na karę konwersji dużej listy na dużą tablicę (nawet oczywiste w przypadku mniejszych list).