Подтвердить что ты не робот

Кэширование скомпилированных объектов регулярных выражений в Python?

Каждый раз, когда импортируется файл python, который содержит большое количество статических регулярных выражений, циклы процессора тратятся на компиляцию строк в их представительные машины состояний в памяти.

a = re.compile("a.*b")
b = re.compile("c.*d")
...

Вопрос: Возможно ли сохранить эти регулярные выражения в кеше на диске в предварительно скомпилированном виде, чтобы избежать необходимости выполнять компиляции регулярных выражений при каждом импорте?

Травление объекта просто делает следующее, в результате чего происходит компиляция:

>>> import pickle
>>> import re
>>> x = re.compile(".*")
>>> pickle.dumps(x)
"cre\n_compile\np0\n(S'.*'\np1\nI0\ntp2\nRp3\n."

И re объекты немаркируются:

>>> import marshal
>>> import re
>>> x = re.compile(".*")
>>> marshal.dumps(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unmarshallable object
4b9b3361

Ответ 1

Возможно ли сохранить эти регулярные выражения в кеше на диске в предварительно скомпилированном виде, чтобы избежать необходимости выполнять компиляции регулярных выражений при каждом импорте?

Не легко. Вам придется написать собственный сериализатор, который перехватывает реализацию C sre механизма регулярного выражения Python. Любые преимущества в производительности будут значительно перевешиваться требуемым временем и усилиями.

Во-первых, вы действительно профилировали код? Я сомневаюсь, что компиляция регулярных выражений является значительной частью времени выполнения приложения. Помните, что они только скомпилированы при первом импортировании модуля в текущем исполнении - после этого модуль и его атрибуты кэшируются в памяти.

Если у вас есть программа, которая в основном порождает один раз, компилирует кучу регулярных выражений, а затем завершает работу, вы можете попробовать перестроить ее для выполнения нескольких тестов в одном вызове. Затем вы можете повторно использовать регулярные выражения, как указано выше.

Наконец, вы можете скомпилировать регулярные выражения на машинах состояния на основе C, а затем связать их с модулем расширения. Хотя это, вероятно, будет сложнее поддерживать, оно полностью исключает компиляцию регулярных выражений из вашего приложения.

Ответ 2

Обратите внимание, что каждый модуль инициализируется только один раз в течение срока действия приложения, независимо от того, сколько раз вы его импортируете. Поэтому, если вы компилируете свои выражения в глобальной области модуля (т.е. Не в функции), вы должны быть в порядке.

Ответ 3

Прежде всего, это явное ограничение в модуле python re. Это приводит к ограничению того, насколько и насколько велики регулярные выражения. Предел больше при длительных процессах и меньше с короткими процессами, такими как приложения командной строки.

Несколько лет назад я посмотрел на него, и можно выкопать результат компиляции, рассолить его, а затем раскрыть его и повторно использовать. Проблема в том, что для этого требуется использование внутренних компонентов sre.py и, следовательно, не будет работать в разных версиях python.

Я хотел бы иметь такую ​​функцию в своем инструменте. Я также хотел бы знать, есть ли какие-то отдельные модули, которые можно было бы использовать вместо этого.

Ответ 4

Модуль shelve работает нормально:


import re
import shelve
a_pattern = "a.*b"
b_pattern = "c.*d"
a = re.compile(a_pattern)
b = re.compile(b_pattern)

x = shelve.open('re_cache')
x[a_pattern] = a
x[b_pattern] = b
x.close()

# ...
x = shelve.open('re_cache')
a = x[a_pattern]
b = x[b_pattern]
x.close()

Затем вы можете создать класс классной оболочки, который автоматически обрабатывает кеширование для вас, чтобы он стал прозрачным для пользователя... упражнение осталось читателю.

Ответ 5

Откройте/usr/lib/python2.5/re.py и найдите "def_compile". Вы найдете re.py механизм внутреннего кэширования.

Ответ 6

Можно поместить каждое регулярное выражение (или группу регулярных выражений) в отдельный файл, а затем динамически импортировать требуемый файл с помощью модуля imp. Я сомневаюсь, что он очень хорошо масштабируется, но это может быть то, что вам нужно.

Ответ 7

Hum,

Не откладывать использование рассола?

В любом случае, я согласен с предыдущими андерсерами. Поскольку модуль обрабатывается только один раз, я сомневаюсь, что регулярные выражения будут вашей шеей для бутылок приложения. И модуль Python re wicked быстро, так как он закодирован в C: -)

Но хорошая новость заключается в том, что Python получил хорошее сообщество, поэтому я уверен, что вы можете найти кого-то, кто сейчас взламывает только то, что вам нужно.

Я googled 5 секунд и нашел: http://home.gna.org/oomadness/en/cerealizer/index.html.

Не знаю, будет ли это делать, но если нет, удачи в исследовании: -)