0

データベースに解析する XML があります。この XML のサイズは約 10 MB で、数百万の要素が含まれています。

30 ~ 60 秒ごとに更新されますが、すべてではなくいくつかの要素のみが更新されます。

データベースへの最速の方法で解析するために、2 つの XML ファイルから重複する要素を削除する関数を開発しました。コードは次のとおりです。

XDocument doc2 = XDocument.Parse(tempDoc.ToString());

var doc1 = new XDocument();
try
{
doc1 = XDocument.Load(bookieName + ".xml");
}
catch
{ }

try
{
var dict1 = doc1.Descendants("event").Select(el => el.ToString()).ToList();
var dict2 = doc1.Descendants("event").Select(el => el.ToString()).ToList();

foreach (var elem in dict1)
{
    if (dict2.Contains(elem))
    {
    if (dict2.Find(x => x == elem).ToString() == dict1.Find(x => x == elem).ToString())
    {
        doc2.Descendants("event").Where(x => x.ToString() == elem).Remove();
    }
    }
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}

return doc2;

問題は、小さな XML ファイルには問題なく機能しますが、大きな XML ファイル (10MB) の場合、2 ~ 5 分間 100% の CPU を使用することです。

どうすればそれを改善し、より良くすることができるか考えていますか?

私はちょっと絶望的です。

ありがとう!

4

4 に答える 4

0

要素を追加する前に、要素がデータベースに存在するかどうかを確認するだけで解決できる場合があります。

また、読み取り中に解析できるように xml リーダーを使用したい場合 (最適なパフォーマンスを得るために)

于 2012-04-19T19:20:57.787 に答える
0

doc2に要素が存在する場合にのみ要素を削除したいようですdoc1が、その逆はありません。

あなたが直面している問題は、非常に非効率的な検索を実行していることです。数百万のレコードがある場合、数百万平方のレコードを効果的に検索しています。

代わりに、リストではなく辞書を使用して、アルゴリズムを大幅に高速化する必要があります。

これを試して:

var dict1 = doc1.Descendants("event").ToDictionary(x => x.ToString(), x => x);
var dict2 = doc2.Descendants("event").ToDictionary(x => x.ToString(), x => x);

var xs = dict1.Keys.Intersect(dict2.Keys).Select(x => dict2[x]);

foreach (var x in xs)
{
    x.Remove();
}

return doc2;

はい、それだけです。私はこれをいくつかのダミーデータ広告でテストしましたが、うまくいきました。

ドキュメント1:

<doc>
  <event>bar</event>
  <event>foo</event>
</doc> 

最初のドキュメント 2:

<doc>
  <event>foo</event>
  <event>qaz</event>
</doc> 

最終文書 2:

<doc>
  <event>qaz</event>
</doc>
于 2012-04-20T05:10:30.643 に答える
0

次の 2 つのことと戦っているようです。

  1. XML は、この種のタスクには適していません (ただし、おそらくあなたの選択ではないことは理解しています)。
  2. ドキュメント全体をXDocument(またはXmlDocument) に読み込むのはコストがかかり、必要ありません

(2) を取り除くには、低レベルのアプローチ (これでは不十分かもしれません) を使用するか、ドキュメント構造を構築せずにイベントベースの XML 解析を行う Java や Perl 風のようなさらに低レベルのアプローチを使用してXmlReaderくださいSAXそのような .net 用のライブラリについては知りません。.NET 用の SAX パーサーのポートがありますが、それがどれほど優れているかはわかりません。XML:Twig

もちろん、以前に解析されたドキュメントからのデータを保持し、新しいドキュメントのみを解析することで、多くの時間を節約できます (しかし、あなたはそれを知っていると確信しています)。

于 2012-04-19T19:29:40.063 に答える
0

ここで行うことは、dict1 のこれらの数百万のイベントのそれぞれについて、dict2 の数百万のイベントを反復処理し、dict1 のすべてのイベントを dict2 のすべてのイベントと比較することです。これにより、何千億もの比較が行われます。これは必要ありません。最初の XML からのすべてのイベントをディクショナリに入れます。次に、2 番目の XML の各イベントについて、同じイベントが最初の XML にも存在するかどうかを辞書で調べます。その場合は、削除してください。辞書での検索は、最初の XML で何百万ものイベントをそれぞれ処理するよりもはるかに高速であり、プログラムも大幅に高速化されます。

于 2012-04-19T20:33:25.020 に答える