online - python split regex
¿Caché de objetos regex compilados en Python? (7)
Cada vez que se importa un archivo Python que contiene una gran cantidad de expresiones regulares estáticas, los ciclos de CPU se pasan compilando las cadenas en sus máquinas de estado representativas en la memoria.
a = re.compile("a.*b")
b = re.compile("c.*d")
...
Pregunta: ¿Es posible almacenar estas expresiones regulares en un caché en el disco de una manera precompilada para evitar tener que ejecutar las compilaciones de expresiones regulares en cada importación?
Decapado del objeto simplemente hace lo siguiente, provocando que la compilación suceda de todos modos:
>>> import pickle
>>> import re
>>> x = re.compile(".*")
>>> pickle.dumps(x)
"cre/n_compile/np0/n(S''.*''/np1/nI0/ntp2/nRp3/n."
Y los objetos re son inmarshallable:
>>> import marshal
>>> import re
>>> x = re.compile(".*")
>>> marshal.dumps(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: unmarshallable object
¿Es posible almacenar estas expresiones regulares en un caché en el disco de una manera precompilada para evitar tener que ejecutar las compilaciones de expresiones regulares en cada importación?
No es fácil. Tendría que escribir un serializador personalizado que se enganche en la implementación sre
del motor de expresiones regulares de Python. Cualquier beneficio de rendimiento sería ampliamente superado por el tiempo y el esfuerzo requerido.
Primero, ¿has perfilado realmente el código? Dudo que compilar expresiones regulares sea una parte importante del tiempo de ejecución de la aplicación. Recuerde que solo se compilan la primera vez que se importa el módulo en la ejecución actual; a continuación, el módulo y sus atributos se guardan en la memoria.
Si tiene un programa que genera básicamente una vez, compila un grupo de expresiones regulares y luego sale, puede intentar reingeniería para realizar múltiples pruebas en una invocación. Entonces podrías reutilizar las expresiones regulares, como se indicó anteriormente.
Finalmente, puede compilar las expresiones regulares en máquinas de estado basadas en C y luego vincularlas con un módulo de extensión. Si bien esto sería más difícil de mantener, eliminaría la compilación regex completamente de su aplicación.
Abra /usr/lib/python2.5/re.py y busque "def _compile". Encontrarás el mecanismo de caché interno de re.py.
El módulo shelve parece funcionar bien:
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()
A continuación, puede crear una buena clase contenedora que maneje automáticamente el almacenamiento en caché para que se vuelva transparente para el usuario ... un ejercicio dejado para el lector.
Es posible colocar cada expresión regular (o grupo de expresiones regulares) en un archivo separado y luego importar dinámicamente el archivo que necesita utilizando el módulo imp. Dudo que se escala muy bien, pero podría ser lo que necesita.
Tararear,
No deja de usar el encurtido?
De todos modos, estoy de acuerdo con los awsers anteriores. Dado que un módulo se procesa solo una vez, dudo que la compilación de expresiones regulares sea el cuello de botella de su aplicación. Y el módulo de Python es muy rápido ya que está codificado en C :-)
Pero la buena noticia es que Python tiene una comunidad agradable, así que estoy seguro de que puedes encontrar a alguien que piratee lo que necesitas.
Busqué en Google 5 segundos y encontré: http://home.gna.org/oomadness/en/cerealizer/index.html .
No sé si lo hará pero si no, buena suerte en su investigación :-)
Tenga en cuenta que cada módulo se inicializa solo una vez durante la vida de una aplicación, sin importar cuántas veces lo importe. Entonces, si compila sus expresiones en el alcance global del módulo (es decir, no en una función), debería estar bien.
En primer lugar, esta es una limitación clara en el módulo python re. Causa un límite de cuánto y qué tan grandes son razonables las expresiones regulares. El límite es mayor con procesos de larga ejecución y más pequeño con procesos de corta duración como aplicaciones de línea de comandos.
Hace algunos años lo miré y es posible desenterrar el resultado de la compilación, desenterrarlo y luego desenfundarlo y reutilizarlo. El problema es que requiere el uso de sre.py internos y por lo tanto probablemente no funcionará en diferentes versiones de Python.
Me gustaría tener este tipo de característica en mi caja de herramientas. También me gustaría saber si hay módulos separados que podrían usarse en su lugar.