ビジネスシーン
30 ~ 40 の正規表現を使用して、3,200 万の文字列が 1 つずつ照合されました。正規一致表現の数が増加し続けると、パフォーマンスは徐々に低下します。
最適化
頻繁に使用される正規表現については、次の方法を使用します。
PATTERN = re.compile("...")
def task(s):
"""被频繁调用的方法"""
PATTERN.search(s)
次の 2 つの方法を使用する代わりに:
PATTERN = re.compile("...")
def task(s):
"""被频繁调用的方法"""
re.search(PATTERN, s)
def task(s):
"""被频繁调用的方法"""
re.search("...", s)
予防
re モジュールを使用する前にドキュメントを読み、頻繁に使用される正規表現については、re.compile
正規表現オブジェクトに初期化するとパフォーマンスが大幅に向上する可能性があることを学びました。したがって、どこでも使用法は次のようになります。
PATTERN = re.compile("...")
def task(s):
"""被频繁调用的方法"""
re.search(PATTERN, s)
ただし、少数のサンプルを抽出して cProfile 統計を使用した後でも、_compile
それが何度も実行され、多くの時間がかかっていることがわかりました。
ncalls tottime percall cumtime percall filename:lineno(function)
......
4159844 4.635 0.000 5.892 0.000 __init__.py:272(_compile)
......
したがって、疑惑re.search()
などの方法は依然として と呼ばれます_compile
。したがって、re.search()
次のようにソースコードを確認します。
def search(pattern, string, flags=0):
"""Scan through string looking for a match to the pattern, returning
a Match object, or None if no match was found."""
return _compile(pattern, flags).search(string)
re._compile()
次のようにソースコードを確認してください。
_cache = {
} # ordered!
_MAXCACHE = 512
def _compile(pattern, flags):
# internal: compile pattern
if isinstance(flags, RegexFlag):
flags = flags.value
try:
return _cache[type(pattern), pattern, flags]
......
re.compile()
このソース コードを通じて、最初に解析して正規表現オブジェクトを他のメソッドに渡すプロセスが、re.search()
文字列を他のメソッドにre.search()
渡してキャッシュを読み取るプロセスと同じであることがわかります。
より高速な方法は、正規表現オブジェクトのsearch()
他のメソッドを直接呼び出すことです。今すぐ:
PATTERN = re.compile("...")
def task(s):
"""被频繁调用的方法"""
PATTERN.search(s)
調整後は、_compile
この方法にはほとんど時間がかかりません。