巨大なファイルをロードするときに、PythonのXMLパーサーの進行状況を表示する
質問
Pythonの組み込みXMLパーサーを使用して1.5ギガのXMLファイルを読み込むと、1日かかります。
from xml.dom import minidom
xmldoc = minidom.parse('events.xml')
プログレスバーを表示できるように、その内部に入り込み、進捗を測定する方法を知る必要があります。 アイデアはありますか?
minidomには、渡す文字列が有効なXMLであると仮定してDOMツリーを返すparseString()と呼ばれる別のメソッドがあります。ファイルを自分でチャンクに分割し、一度に1つずつparseStringに渡す場合、すべてのDOMツリーを最後にマージしますか?
解決
ユースケースでは、domの代わりにsaxパーサーを使用する必要があります 効果的である可能性があり、進行状況インジケータも作成できます
また、非常に役立つexpatパーサーを試すことをお勧めします http://docs.python.org/library/pyexpat.html
saxを使用した進行状況:
saxはファイルをインクリメンタルに読み取るので、渡したファイルオブジェクトを自分でラップして、読み取られた量を追跡できます。
編集: また、ファイルを自分で分割して最後にDOMに参加するという考えも好きではないので、独自のxmlパーサーを書く方が良いので、代わりにsaxパーサーの使用をお勧めします また、DOMツリーで1.5ギガのファイルを読み取る目的は何でしょうか? ここではサックスの方が良いように見えます
他のヒント
XMLを解析する他の手段を使用することを検討しましたか?このような大きなXMLファイルのツリーの構築は、常に低速で、メモリを集中的に使用します。メモリ内のツリー全体を必要としない場合、ストリームベースの解析はずっと高速になります。ツリーベースのXML操作に慣れている場合は少し気が遠くなるかもしれませんが、速度が大幅に向上します(時間ではなく分)。
PullQM APIではなく、PyQtではなくPyGTKに非常によく似たものがあります。 Gtkアイドルイベント(GUIがロックしない)とPythonジェネレーター(解析状態を保存するため)を使用して、少しずつ呼び出されます。
def idle_handler (fn):
fh = open (fn) # file handle
doc = xml.dom.pulldom.parse (fh)
fsize = os.stat (fn)[stat.ST_SIZE]
position = 0
for event, node in doc:
if position != fh.tell ():
position = fh.tell ()
# update status: position * 100 / fsize
if event == ....
yield True # idle handler stays until False is returned
yield False
def main:
add_idle_handler (idle_handler, filename)
ツリーの最後でのマージは非常に簡単です。新しいDOMを作成し、基本的に個々のツリーを1つずつ追加できます。これにより、解析の進行状況を非常に細かく制御できます。異なるプロセスを生成して各セクションを解析することで、必要に応じて並列化することもできます。インテリジェントに分割する必要があります(タグの途中で分割しないなど)。