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 CreateReader
każ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 StringBuilder
metody Aggregate, ale nie ponad CreateReader
. Nie sądzę, aby metody Join
i Concat
był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).