@@ -105,19 +105,28 @@ def _qualify_link(*xs):
105105 }
106106
107107
108- class Qualifier (object ):
108+ # 修飾行のパース用正規表現。QualifyDictionary のコマンド一覧は不変なので、
109+ # モジュール読み込み時に一度だけ構築し Qualifier ごとの再コンパイルを避ける。
110+ _QUALIFY_DICTIONARY = QualifyDictionary ()
111+ _QUALIFY_LINE_RE = re .compile (
112+ r'^[ \t]*\*[ \t]+(?P<target>.*?)(?P<commands>({commands})+)$' .format (
113+ commands = '|' .join (r'(\[{cmd}(\]|.*?\]))' .format (cmd = cmd ) for cmd in _QUALIFY_DICTIONARY .qualify_dic )))
109114
110- """修飾1個分のデータを保持するクラス"""
115+ # 同一の修飾行から作られる Qualifier はコンパイル済み正規表現ごと使い回せる
116+ # (target/commands は行文字列から決まる不変値で find_match は状態を持たない)。
117+ # GLOBAL_QUALIFY_LIST の各行は全コードブロックで共通なので、ここで共有すること
118+ # でコードブロック単位に発生していた大量の正規表現コンパイルを削減する。
119+ # パースに失敗した行は None を記憶して再試行しない。
120+ _QUALIFIER_CACHE = {}
111121
112- def __init__ (self , line , qdic ):
113- command_res = [r'(\[{cmd}(\]|.*?\]))' .format (cmd = cmd ) for cmd in qdic .qualify_dic ]
114122
115- qualify_re_str = r'^[ \t]*\*[ \t]+(?P<target>.*?)(?P<commands>({commands})+)$' . format (
116- commands = '|' . join ( command_res ))
117- qualify_re = re . compile ( qualify_re_str )
123+ class Qualifier ( object ):
124+
125+ """修飾1個分のデータを保持するクラス"""
118126
127+ def __init__ (self , line , qdic = None ):
119128 # parsing
120- m = qualify_re .search (line )
129+ m = _QUALIFY_LINE_RE .search (line )
121130 if not m :
122131 raise ValueError ('Failed parse' )
123132 self .target = m .group ('target' )
@@ -156,19 +165,26 @@ def find_match(self, code):
156165class QualifierList (object ):
157166
158167 def __init__ (self , lines ):
159- self ._qdic = QualifyDictionary ()
168+ self ._qdic = _QUALIFY_DICTIONARY
160169
161- # Qualifier を作るが、エラーになったデータは取り除く
170+ # Qualifier を作るが、エラーになったデータは取り除く。同一行はキャッシュ
171+ # から共有し正規表現の再コンパイルを避ける (エラー行は None を記憶)。
162172 def unique (xs ):
163173 seen = set ()
164174 results = []
165175 for x in xs :
166- if x not in seen :
167- seen .add (x )
176+ if x in seen :
177+ continue
178+ seen .add (x )
179+ q = _QUALIFIER_CACHE .get (x , False )
180+ if q is False :
168181 try :
169- results . append ( Qualifier (x , self . _qdic ) )
182+ q = Qualifier (x )
170183 except Exception :
171- pass
184+ q = None
185+ _QUALIFIER_CACHE [x ] = q
186+ if q is not None :
187+ results .append (q )
172188 return results
173189
174190 self ._qs = unique (lines )
0 commit comments