Кэширование скомпилированных объектов регулярных выражений в 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
Ответы
Ответ 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.
Не знаю, будет ли это делать, но если нет, удачи в исследовании: -)