Ответ 1
Первое, что приходит на ум, - это нажать цикл на сторону C, используя выражение генератора:
def matches_pattern(s, patterns):
return any(p.match(s) for p in patterns)
Возможно, вам даже не нужна отдельная функция для этого.
Еще одна вещь, которую вы должны попробовать - это создать единое составное регулярное выражение с помощью оператора чередования |
, чтобы у двигателя появилась возможность его оптимизировать. Вы также можете динамически создать динамическое выражение из списка шаблонов строк, если это необходимо:
def matches_pattern(s, patterns):
return re.match('|'.join('(?:%s)' % p for p in patterns), s)
Конечно, вам нужно иметь регулярные выражения в строковой форме для этого. Просто выполните профиль обоих и проверьте, какой из них быстрее:)
Вы также можете просмотреть общий совет для отладки регулярных выражений в Python. Это также может помочь найти возможности для оптимизации.
ОБНОВЛЕНИЕ: Мне было любопытно и написал небольшой ориентир:
import timeit
setup = """
import re
patterns = [".*abc", "123.*", "ab.*", "foo.*bar", "11010.*", "1[^o]*"]*10
strings = ["asdabc", "123awd2", "abasdae23", "fooasdabar", "111", "11010100101", "xxxx", "eeeeee", "dddddddddddddd", "ffffff"]*10
compiled_patterns = list(map(re.compile, patterns))
def matches_pattern(str, patterns):
for pattern in patterns:
if pattern.match(str):
return True
return False
def test0():
for s in strings:
matches_pattern(s, compiled_patterns)
def test1():
for s in strings:
any(p.match(s) for p in compiled_patterns)
def test2():
for s in strings:
re.match('|'.join('(?:%s)' % p for p in patterns), s)
def test3():
r = re.compile('|'.join('(?:%s)' % p for p in patterns))
for s in strings:
r.match(s)
"""
import sys
print(timeit.timeit("test0()", setup=setup, number=1000))
print(timeit.timeit("test1()", setup=setup, number=1000))
print(timeit.timeit("test2()", setup=setup, number=1000))
print(timeit.timeit("test3()", setup=setup, number=1000))
Выход на моей машине:
1.4120500087738037
1.662621021270752
4.729579925537109
0.1489570140838623
Итак, any
, похоже, не быстрее вашего первоначального подхода. Динамическое создание динамического выражения также не очень быстро. Но если вам удастся создать регулярное выражение и использовать его несколько раз, это может привести к повышению производительности. Вы также можете адаптировать этот тест для тестирования некоторых других вариантов:)