次の Python コードを検討してください。
import timeit
import re
def one():
any(s in mystring for s in ('foo', 'bar', 'hello'))
r = re.compile('(foo|bar|hello)')
def two():
r.search(mystring)
mystring="hello"*1000
print([timeit.timeit(k, number=10000) for k in (one, two)])
mystring="goodbye"*1000
print([timeit.timeit(k, number=10000) for k in (one, two)])
基本的に、大きな文字列内のいくつかの部分文字列のうちの 1 つの存在を確認する 2 つの方法をベンチマークしています。
ここで得られるもの (Python 3.2.3) は次の出力です。
[0.36678314208984375, 0.03450202941894531]
[0.6672089099884033, 3.7519450187683105]
最初のケースでは、正規表現は式を簡単に打ち負かしますany
。正規表現は部分文字列をすぐに見つけますany
が、正しい部分文字列に到達する前に文字列全体を数回チェックする必要があります。
しかし、2 番目の例では何が起こっているのでしょうか。部分文字列が存在しない場合、正規表現は驚くほど遅くなります! 理論的には、正規表現は文字列を 1 回だけ通過する必要があるのに対し、any
式は文字列を 3 回通過する必要があるため、これには驚かされます。ここで何が問題なのですか?私の正規表現に問題がありますか、それともこの場合 Python の正規表現が単に遅いのでしょうか?