3

いくつかのフィールドの内容を抽出する必要がある XML ファイルでいっぱい (~10 3、10 4 ) のディレクトリがあります。私はさまざまな xml パーサーをテストしましたが、コンテンツを検証する必要がない (高価な) ため、単純に xml.parsers.expat (最速のもの) を使用してファイルを 1 つずつ抽出することを考えていました。データ。

  1. より効率的な方法はありますか?(単純なテキスト マッチングは機能しません)
  2. 新しいファイル (または文字列) ごとに新しい ParserCreate() を発行する必要がありますか?それとも、すべてのファイルで同じものを再利用できますか?
  3. 注意事項はありますか?

ありがとう!

4

4 に答える 4

4

通常、私は ElementTree の を使用することをお勧めしますiterparse。または、余分な速度のためにlxmlの対応するものを使用することをお勧めします。また、Processing (2.6 に組み込まれています) を使用して並列化してみてください。

重要なことiterparseは、要素 (サブ) 構造が解析されるときに取得することです。

import xml.etree.cElementTree as ET
xml_it = ET.iterparse("some.xml")
event, elem = xml_it.next()

eventこの場合、常に文字列"end"になりますが、パーサーを初期化して、解析された新しい要素についても通知することもできます。その時点ですべての子要素が解析されるという保証はありませんが、それだけに関心がある場合は、属性はそこにあります。

もう 1 つのポイントは、イテレータからの要素の読み取りを早い段階で、つまりドキュメント全体が処理される前に停止できることです。

ファイルが大きい場合 (そうですか?)、ストリーミング パーサーと同じように、メモリ使用量を一定に保つための一般的な慣用句があります。

于 2008-12-08T13:01:56.507 に答える
3

最も簡単な方法は、XMLを解析する代わりに、文字列(正規表現など)を照合することです。XMLによっては、これが実際に機能する可能性があります。

しかし、最も重要なことはこれです。いくつかのオプションを検討する代わりに、それらを実装して小さなセットで時間を計るだけです。これにはほぼ同じ時間がかかり、実数があなたを前進させます。

編集:

  • ファイルはローカルドライブまたはネットワークドライブにありますか?ネットワークI/Oはここであなたを殺します。
  • 問題は簡単に並列化されます。作業を複数のコンピューター(またはマルチコアコンピューター上の複数のプロセス)に分割できます。
于 2008-12-05T18:08:02.210 に答える
1

あなたが示していないことの 1 つは、XML を何らかの DOM に読み込んでいるかどうかです。おそらくそうではないと思いますが、万が一そうである場合は、しないでください。代わりに xml.sax を使用してください。DOM の代わりに SAX を使用すると、パフォーマンスが大幅に向上します。

于 2008-12-06T00:52:34.390 に答える
1

XML ファイルが常に同じアルゴリズムを使用して生成されることがわかっている場合は、XML 解析をまったく実行しない方が効率的かもしれません。たとえば、データが 3 行目、4 行目、5 行目にあることがわかっている場合、ファイルを 1 行ずつ読み込んでから、正規表現を使用できます。

もちろん、ファイルがマシンで生成されたものではない場合、または別のジェネレーターから生成されたものである場合、またはジェネレーターが時間の経過とともに変化する場合、そのアプローチは失敗します。しかし、私はそれがより効率的であると楽観的です

パーサー オブジェクトをリサイクルするかどうかは、ほとんど関係ありません。さらに多くのオブジェクトが作成されるため、単一のパーサー オブジェクトはあまりカウントされません。

于 2008-12-05T17:49:00.673 に答える