Pythonの正規表現モジュールにおけるコンパイルの効果を検証
「Pythonで正規表現による文字列処理(検索・置換・分割)を行う」の中で、「同じパターンを複数回使用する状況下では、正規表現のコンパイルを行って正規表現オブジェクトを作成して使い回したほうが、毎回関数を呼ぶやり方より処理時間が短縮される」ということに触れた。
ここでは、実際にどれほどの違いが出るのかを実験してみることにする。
[任意]ファイル名: recachetest.py
#! /usr/bin/python # -*- encoding: utf-8 -*- from optparse import OptionParser import time import re def search_nocompile(str, pattstr, cnt): """ 文字列strをパターンpattstrでcnt回検索(検索を行うだけ) """ for x in range(cnt): re.search(pattstr, str) # パターンを毎回コンパイルして使い捨てている def search_compile(str, pattobj, cnt): """ 文字列strを(コンパイルされた)正規表現オブジェクトpattobjでcnt回検索 """ for x in range(cnt): pattobj.search(str) # コンパイルされたものを使い回している def main(): """ メイン処理 """ parser_defaults = { "string" : "test string [http://d.hatena.ne.jp/kakurasan/:title=link]", "pattern" : "\[(http://.+?):title=(.+?)\]", "count" : 1000000, "compile" : False, } parser = OptionParser() parser.set_defaults(**parser_defaults) parser.add_option("-s", "--string", dest="string", action="store", type="string", help=u"文字列STRINGの繰り返しを使用します".encode("utf-8"), metavar="STRING") parser.add_option("-p", "--pattern", dest="pattern", action="store", type="string", help=u"検索するパターンを指定します".encode("utf-8"), metavar="PATTERN") parser.add_option("-t", "--count", dest="count", action="store", type="int", help=u"COUNT回のマッチを繰り返し行います".encode("utf-8"), metavar="COUNT") parser.add_option("-c", "--compile", dest="compile", action="store_true", help=u"コンパイルを行います".encode("utf-8")) (options, args) = parser.parse_args() time_before = int(time.time()) # 開始前の時刻 if options.compile == True: print u"コンパイルを行います".encode("utf-8") patt = re.compile(options.pattern) search_compile(options.string, patt, options.count) else: print u"コンパイルを行いません".encode("utf-8") search_nocompile(options.string, options.pattern, options.count) time_after = int(time.time()) # 終了時の時刻 print u"所要時間: 約 %d 秒".encode("utf-8") % (time_after - time_before) if __name__ == "__main__": main()
処理としては、コンパイルをして使い回す場合と使い捨てる場合のそれぞれで、同じ文字列・同じパターンを使用して検索処理を繰り返しているだけ。
下は実行例。オプション指定により、ある程度の調整ができるようにしてある。
$ ./recachetest.py -h usage: recachetest.py [options] options: -h, --help show this help message and exit -s STRING, --string=STRING 文字列STRINGの繰り返しを使用します -p PATTERN, --pattern=PATTERN 検索するパターンを指定します -t COUNT, --count=COUNT COUNT回のマッチを繰り返し行います -c, --compile コンパイルを行います $ ./recachetest.py コンパイルを行いません 所要時間: 約 14 秒 $ ./recachetest.py -c コンパイルを行います 所要時間: 約 8 秒