Pregunta

Cada vez que se importa un archivo Python que contiene una gran cantidad de expresiones regulares estáticas, se emplean ciclos de CPU para compilar 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 forma precompilada para evitar tener que ejecutar las compilaciones de expresiones regulares en cada importación?

Decapar el objeto simplemente hace lo siguiente, provocando que la compilación se realice 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 re Los objetos no se pueden ordenar:

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

Solución

¿Es posible almacenar estas expresiones regulares en un caché en el disco de forma precompilada para evitar tener que ejecutar las compilaciones de expresiones regulares en cada importación?

No es fácil.Tendrías que escribir un serializador personalizado que se conecte a C sre Implementación del motor de expresiones regulares Python.Cualquier beneficio de rendimiento sería ampliamente superado por el tiempo y el esfuerzo requeridos.

Primero, ¿ha 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 partir de entonces, el módulo y sus atributos se almacenan en caché en la memoria.

Si tiene un programa que básicamente se genera una vez, compila un montón de expresiones regulares y luego sale, puede intentar rediseñarlo para realizar múltiples pruebas en una sola 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 probablemente sería más difícil de mantener, eliminaría por completo la compilación de expresiones regulares de su aplicación.

Otros consejos

Tenga en cuenta que cada módulo se inicializa solo una vez durante la vida de una aplicación, sin importar cuántas veces la importe.Entonces, si compila sus expresiones en el alcance global del módulo (es decir,no en una función) deberías estar bien.

En primer lugar, esta es una limitación clara en el módulo re de Python.Provoca un límite en cuánto y en qué tamaño son razonables las expresiones regulares.El límite es mayor con procesos de larga ejecución y menor con procesos de corta duración, como aplicaciones de línea de comandos.

Hace algunos años lo miré y es posible extraer el resultado de la compilación, encurtirlo y luego deshacerlo y reutilizarlo.El problema es que requiere el uso de las partes internas de sre.py y, por lo tanto, probablemente no funcionará en diferentes versiones de Python.

Me gustaría tener este tipo de función en mi caja de herramientas.También me gustaría saber si hay módulos separados que podrían usarse en su lugar.

El dejar de lado El módulo 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()

Luego puede crear una buena clase contenedora que maneje automáticamente el almacenamiento en caché para que sea transparente para el usuario...Un ejercicio dejado al lector.

Abra /usr/lib/python2.5/re.py y busque "def _compile".Encontrarás el mecanismo de caché interno de re.py.

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 usando el módulo imp.Dudo que se escale muy bien pero podría ser lo que necesitas.

Tararear,

¿No se utilizan pepinillos en los estantes?

De todos modos, estoy de acuerdo con las respuestas anteriores.Dado que un módulo se procesa solo una vez, dudo que compilar expresiones regulares sea el cuello de botella de su aplicación.Y el módulo Python re es tremendamente rápido ya que está codificado en C :-)

Pero la buena noticia es que Python tiene una buena comunidad, así que estoy seguro de que puedes encontrar a alguien que esté pirateando justo lo que necesitas.

Busqué en Google durante 5 segundos y encontré: http://home.gna.org/oomadness/en/cerealizer/index.html.

No sé si funcionará, pero si no, buena suerte en tu investigación :-)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top