20

大量の静的正規表現を含むPythonファイルがインポートされるたびに、CPUサイクルは、メモリ内の代表的なステートマシンに文字列をコンパイルするために費やされます。

a = re.compile("a.*b")
b = re.compile("c.*d")
...

質問:インポートごとに正規表現のコンパイルを実行する必要がないように、これらの正規表現を事前にコンパイルされた方法でディスク上のキャッシュに保存することは可能ですか?

オブジェクトをピクルスにすると、次のようになり、とにかくコンパイルが発生します。

>>> import pickle
>>> import re
>>> x = re.compile(".*")
>>> pickle.dumps(x)
"cre\n_compile\np0\n(S'.*'\np1\nI0\ntp2\nRp3\n."

そして、reオブジェクトはマーシャリングできません:

>>> import marshal
>>> import re
>>> x = re.compile(".*")
>>> marshal.dumps(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unmarshallable object
4

7 に答える 7

13

これらの正規表現を事前にコンパイルされた方法でディスク上のキャッシュに保存して、インポートごとに正規表現のコンパイルを実行する必要がないようにすることは可能ですか?

簡単ではありません。srePython 正規表現エンジンの C 実装にフックするカスタム シリアライザーを作成する必要があります。必要な時間と労力は、パフォーマンス上のメリットをはるかに上回ります。

まず、実際にコードをプロファイリングしましたか? 正規表現のコンパイルがアプリケーションの実行時間の重要な部分であるとは思えません。それらは、モジュールが現在の実行で最初にインポートされたときにのみコンパイルされることに注意してください。その後、モジュールとその属性はメモリにキャッシュされます。

基本的に一度スポーンし、一連の正規表現をコンパイルしてから終了するプログラムがある場合は、1 回の呼び出しで複数のテストを実行するように再設計することができます。次に、上記のように正規表現を再利用できます。

最後に、正規表現を C ベースのステート マシンにコンパイルし、それらを拡張モジュールにリンクすることができます。これは維持するのがより困難になる可能性がありますが、アプリケーションから正規表現のコンパイルが完全に排除されます。

于 2008-09-15T18:29:51.187 に答える
3

各モジュールは、何回インポートしても、アプリの有効期間中に一度だけ初期化されることに注意してください。したがって、モジュールのグローバル スコープ (つまり、関数内ではない) で式をコンパイルする場合は問題ありません。

于 2008-09-15T18:16:24.277 に答える
2

まず第一に、これは python re モジュールの明らかな制限です。これにより、正規表現の妥当な量と大きさが制限されます。この制限は、長時間実行されるプロセスでは大きくなり、コマンド ライン アプリケーションなどの短期間のプロセスでは小さくなります。

数年前に私はそれを見ましたが、コンパイル結果を掘り出し、それをピクルしてからアンピクルして再利用することが可能です。問題は、sre.py 内部を使用する必要があるため、異なる python バージョンではおそらく動作しないことです。

ツールボックスにこの種の機能を追加したいと考えています。また、代わりに使用できる別のモジュールがあるかどうかも知りたいです。

于 2008-12-28T13:02:56.863 に答える
0

shelveモジュールは問題なく動作しているようです。


import re
import shelve
a_pattern = "a.*b"
b_pattern = "c.*d"
a = re.compile(a_pattern)
b = re.compile(b_pattern)

x = shelve.open('re_cache')
x[a_pattern] = a
x[b_pattern] = b
x.close()

# ...
x = shelve.open('re_cache')
a = x[a_pattern]
b = x[b_pattern]
x.close()

次に、キャッシングを自動的に処理する素敵なラッパー クラスを作成して、ユーザーに対して透過的にすることができます。演習は読者に任せます。

于 2008-09-15T19:14:24.730 に答える
0

/usr/lib/python2.5/re.py を開き、「def _compile」を探します。re.py の内部キャッシュ メカニズムがわかります。

于 2008-09-15T20:53:14.900 に答える
-1

ハム、

ピクルスを使わないの?

とにかく、私は以前の答えに同意します。モジュールは1回しか処理されないため、正規表現のコンパイルがアプリのボトルネックになるとは思えません。そして、Python reモジュールはCでコーディングされているため、高速に動作します:-)

しかし、良いニュースは、Pythonが素晴らしいコミュニティを獲得したことです。そのため、現在必要なものだけをハッキングしている人を見つけることができると確信しています。

私は5秒グーグルで見つけました:http://home.gna.org/oomadness/en/cerealizer/index.html

それがうまくいくかどうかはわかりませんが、そうでない場合は、研究して頑張ってください:-)

于 2008-09-15T20:34:12.480 に答える
-1

各正規表現 (または正規表現のグループ) を個別のファイルに配置し、imp モジュールを使用して必要なファイルを動的にインポートすることができます。それが非常にうまくスケーリングできるとは思えませんが、必要なものになる可能性があります。

于 2008-09-15T18:45:37.717 に答える