11

ある講義で使用するいくつかのファイル形式 ( ARFF )用に、実践的な再帰的な純粋な python パーサーを作成しました。現在、私のエクササイズ提出の実行が非常に遅いです。私のパーサーで最も多くの時間が費やされていることがわかりました。多くの CPU 時間を消費しています。HD がボトルネックではありません。

Python でパーサーを作成するには、どのようなパフォーマンスの高い方法があるのだろうか? Cで書き直したくないので、jythonを使おうとしましたが、パフォーマンスが大幅に低下しました。私が解析したファイルは部分的に巨大 (> 150 MB) で、非常に長い行があります。

私の現在のパーサーは、1 文字の先読みしか必要としません。ここにソースを投稿しますが、それが良いアイデアかどうかはわかりません。やはり提出期限はまだ終わっていません。ただし、この演習の焦点はパーサーではありません。使用したい言語を選択でき、Java 用のパーサーが既に用意されています。

注: 私は x86_64 システムを使用しているため、サイコ (および PyPy のようにも見えます) はオプションではありません。

更新: パーサー/ライターをbitbucketにアップロードしました。

4

2 に答える 2

10

ANTLRまたはpyparsingを使用できます。解析プロセスが高速化される可能性があります。

また、現在のコードを維持したい場合は、Cython / PyPyを検討することをお勧めします。これにより、パフォーマンスが向上します (場合によっては最大 4 倍)。

于 2010-04-27T16:30:29.487 に答える
9

詳細な情報がなくても、私が提供する最も一般的なヒントは、ファイル全体、または少なくともそのかなりの部分を一度にメモリに読み込むことです。一度に 1 文字ずつ読んであちこち探してはいけません。ボンネットの下で行われているバッファリングに関係なく、すべてをメモリに保持して、必要に応じて操作できるようにすることをお勧めします。

私は Python でパーサーを作成しましたが、他の言語で作成されたパーサーよりも特に遅くなければならないという特別な要件はありません。このようなことと同様に、必要のない仕事をしている可能性が高くなります。これらのクラスのアイテムの中で、同じオブジェクトを作成して破棄し、再作成することは、単にどこかに保管するよりもコストがかかります。値を何度も再計算すると、単にどこかに保存するよりもコストがかかります。などなど

特に Python では、不必要な文字列操作を大量に行うという落とし穴があります。一度に 1 文字ずつ文字列に追加しないでください。トークンを構築するときは、「マスター」文字列で作業を行い、トークンを一挙に取り除きます。(つまり、「マスター」文字列にインデックスを付け、開始点と終了点を把握し、それを で取得しtoken = master[start:end]ます。) 一度に 1 文字ずつ文字列連結を行うことは、パフォーマンスの悲惨さへの近道です。何らかの理由でやりたい/必要があるとしてもfor c in master: newstr += c、「c」をリストに詰め込んでからnewstr = ''.join(newstr_charlist).

于 2010-04-27T17:03:44.067 に答える