2008年5月4日日曜日

re.compileの結果をcacheする。

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
タイプを減らしたいからクラス変数に固定的初期化するという手抜きをしていたが、数行核だけでre.compile済みのものを使えるようにした。ネットワークの通信内容をパースする正規表現だけに劇的に軽くなった。
nameエラーがraiseされたときにcompileするのも手だが、yieldとは併用できない。

前にもscaleした画像をcacheするコードを実装したが、この手のメモ化はコーディングコスト(数行)の割に効果が大きく(10倍オーダー)うれしい。

あ・・・クラスでcacheをもったほうがいいなぁ、これ。そうすればキャッシュをインスタンス間で共有できる。

class State(object):
def __init__(self):
self.regexp_cache = dict()

def __iter__(self):
for name, value in self.__class__.__dict__.items():
if name.startswith('CLIP') or name.startswith('FIBS'):
if name not in self.regexp_cache:
self.regexp_cache.update({name: [re.compile(regexp) for regexp in valu
e]})
for regexp in self.regexp_cache[name]:
yield name, regexp

中略

class LoginState(State):
FIBS_LoginPrompt = ["^login:", ]
CLIP_WELCOME = ["^1 [a-zA-Z_<>]+ [0-9]+ ",]
CLIP_OWN_INFO = ["^2 [a-zA-Z_<>]+ [01] [01]"]
CLIP_MOTD_BEGIN = ["^3$"]