69

カスタムオブジェクトを最適化しています-> XMLシリアライゼーションユーティリティ、それはすべて完了して機能しており、それは問題ではありません。

ファイルをXmlDocumentオブジェクトにロードし、すべての子ノードを再帰的に通過することで機能しました。

XmlReader全体をロード/解析する代わりに使用XmlDocumentする方が速いのではないかと考えたので、そのバージョンも実装しました。

アルゴリズムはまったく同じです。ラッパー クラスを使用して、 an と an を処理する機能を抽象化しXmlNodeますXmlReader。たとえば、GetChildrenメソッド yield は子XmlNodeまたは SubTreeを返しますXmlReader

そこで、重要なデータ セット (約 1,350 の要素を含む 900 KB の XML ファイル) を使用して、両方のバージョンをテストするためのテスト ドライバーを作成しました。

しかし、JetBrains dotTRACE を使用すると、XmlReader実際にはバージョンがバージョンよりも遅いことがわかりますXmlDocumentXmlReader子ノードを繰り返し処理しているときに、読み取り呼び出しに関連する重要な処理がいくつかあるようです。

だから私はこれを尋ねるためにすべてを言います:

と の長所と短所はXmlDocumentXmlReaderですか? また、どのような状況でどちらを使用する必要がありますか?

私の推測ではXmlReader、パフォーマンスがより経済的になり、メモリの消費量が少なくなるファイル サイズのしきい値があると思います。ただし、そのしきい値は 1MB を超えているようです。

ReadSubTree子ノードを処理するために毎回呼び出しています:

public override IEnumerable<IXmlSourceProvider> GetChildren ()
{
    XmlReader xr = myXmlSource.ReadSubtree ();
    // skip past the current element
    xr.Read ();

    while (xr.Read ())
    {
        if (xr.NodeType != XmlNodeType.Element) continue;
        yield return new XmlReaderXmlSourceProvider (xr);
    }
}

このテストは、1 つのレベル (つまり、広くて浅い) で多くのオブジェクトに適用されますXmlReader。つまり、私が扱っている XML は、データ オブジェクト モデル、1 つの親オブジェクトから多くの子オブジェクトなどによく似ています。1..M..M..M

また、解析している XML の構造が事前にわからないため、最適化できません。

4

5 に答える 5

74

私は通常、最速の観点からではなく、メモリ使用率の観点から見てきました。すべての実装は、私が使用した使用シナリオ (典型的なエンタープライズ統合) に対して十分に高速でした。

しかし、私が失敗したのは、時には見事に、私が扱っている XML の一般的なサイズを考慮に入れていなかったことです。事前に考えておけば、多少の悲しみは避けられます。

XML は、少なくともXmlDocumentやのような DOM リーダーを使用すると、メモリにロードされると肥大化する傾向がありますXPathDocument。10:1くらい?正確な量を定量化するのは困難ですが、たとえば、ディスク上で 1MB の場合、メモリでは 10MB またはそれ以上になります。

ドキュメント全体をメモリに完全にロードするリーダーを使用するプロセス ( XmlDocument/ XPathDocument) は、大きなオブジェクト ヒープの断片化に悩まされる可能性があり、最終的にはOutOfMemoryExceptions (利用可能なメモリがある場合でも) が発生し、サービス/プロセスが利用できなくなる可能性があります。

サイズが 85K を超えるオブジェクトは最終的に大きなオブジェクト ヒープになり、DOM リーダーで 10:1 のサイズ爆発が発生するため、XML ドキュメントが割り当てられるまでにそれほど時間はかからないことがわかります。大きなオブジェクト ヒープ。

XmlDocument非常に使いやすいです。唯一の本当の欠点は、XML ドキュメント全体をメモリにロードして処理することです。その魅惑的な使い方は簡単です。

XmlReaderストリームベースのリーダーであるため、プロセスのメモリ使用率は一般的にフラットに保たれますが、使いにくいです。

XPathDocumentXmlDocument の高速な読み取り専用バージョンになる傾向がありますが、それでもメモリの「膨張」に悩まされます。

于 2009-10-01T20:35:10.733 に答える
11

XmlDocument は、XML ドキュメント全体のメモリ内表現です。したがって、ドキュメントが大きい場合、XmlReader を使用して読み取った場合よりもはるかに多くのメモリを消費します。

これは、XmlReader を使用するときに、要素を 1 つずつ読み取って処理してから破棄することを前提としています。XmlReader を使用してメモリ内に別の中間構造を構築すると、同じ問題が発生し、その目的が無効になります。

XML を処理する 2 つのモデルの違いについて詳しくは、 「 SAX vs DOM 」をGoogle で検索してください。

于 2009-10-01T20:08:32.390 に答える
4

もう 1 つの考慮事項は、XMLReader は、完全ではない形式の XML を処理する場合により堅牢である可能性があることです。最近、XML ストリームを使用するクライアントを作成しましたが、ストリームには、一部の要素に含まれる URI で正しくエスケープされた特殊文字がありませんでした。XMLDocument と XPathDocument は XML の読み込みをまったく拒否しましたが、XMLReader を使用すると、ストリームから必要な情報を抽出できました。

于 2015-04-13T16:03:07.097 に答える
0

エンコードの違いは、2 つの異なる測定値が混在しているためです。UTF-32 は 1 文字あたり 4 バイトを必要とし、1 バイト データよりも本質的に低速です。

大規模な (100K) 要素のテストを見ると、使用した読み込み方法に関係なく、各ケースで時間が約 70mS 増加することがわかります。

これは、特に文字ごとのオーバーヘッドによって引き起こされる (ほぼ) 一定の違いです。

于 2012-11-11T15:52:28.947 に答える
0

XmlDocument が遅くなり、最終的に使用できなくなるサイズのしきい値があります。ただし、しきい値の実際の値はアプリケーションと XML コンテンツに依存するため、厳格な規則はありません。

XML ファイルに大きなリスト (数万の要素など) を含めることができる場合は、間違いなく XmlReader を使用する必要があります。

于 2009-10-01T16:43:27.340 に答える