これらの提案されたソリューションのどれが最も効果的かを確認したかったので、いくつかの比較テストを実行しました。興味深いことに、私はLINQメソッドを、Gregによって提案されたプレーンな古いSystem.Xmlメソッドと比較しました。変化は興味深いものであり、予想したものではありませんでした。最も遅い方法は、最も速い方法よりも3倍以上遅くなっています。
結果は、速いものから遅いものの順に並べられました。
- CreateReader-インスタンスハンター(0.113秒)
- プレーンな古いSystem.Xml-Greg Hurlman(0.134秒)
- 文字列連結による集計-Mike Powell(0.324秒)
- StringBuilder-Vin(0.333秒)
- String.Join on array-Terry(0.360秒)
- 配列のString.Concat-Marcin Kosieradzki(0.364)
方法
20個の同一のノード(「ヒント」と呼ばれる)を含む単一のXMLドキュメントを使用しました。
<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>
上記の秒数は、20ノードの「内部XML」を1000回続けて抽出し、5回の実行の平均(平均)をとった結果です。XMLをXmlDocument
(System.Xmlメソッドの場合)またはXDocument
(その他すべての場合)にロードして解析するのにかかる時間は含めませんでした。
私が使用したLINQアルゴリズムは次のとおりです:(C#-すべてXElement
「親」を取り、内部XML文字列を返します)
CreateReader:
var reader = parent.CreateReader();
reader.MoveToContent();
return reader.ReadInnerXml();
文字列を連結して集計:
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:
return String.Join("", parent.Nodes().Select(x => x.ToString()).ToArray());
配列のString.Concat:
return String.Concat(parent.Nodes().Select(x => x.ToString()).ToArray());
ノードで.InnerXmlを呼び出すだけなので、ここでは「プレーンな古いSystem.Xml」アルゴリズムを示していません。
結論
パフォーマンスが重要である場合(たとえば、大量のXMLが頻繁に解析される場合)、毎回DanielのCreateReader
方法を使用します。いくつかのクエリを実行しているだけの場合は、Mikeのより簡潔なAggregateメソッドを使用することをお勧めします。
多数のノード(おそらく100のノード)を持つ大きな要素でXMLを使用StringBuilder
している場合、Aggregateメソッドではなく、ではなくAggregateメソッドを使用することの利点がわかるでしょうCreateReader
。大きなリストを大きな配列に変換するペナルティ(ここでは小さなリストでも明らかです)が原因で、これらの条件ではJoin
and Concat
メソッドが効率的になるとは思いません。