2008-09-15 26 views
18

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.Almacenamiento en memoria caché de objetos regex compilados en Python?

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

Pregunta: ¿Es posible almacenar estas expresiones regulares en una memoria caché en el disco de una manera pre-compilados para evitar tener que ejecutar las compilaciones de expresiones regulares en cada importación?

Decapado el objeto simplemente hace lo siguiente, causando la compilación a suceder 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 objetos son unmarshallable:

>>> 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

Tristemente, mi aplicación (900 expresiones regulares y conteo) también tiene este problema. desafortunadamente, no veo ninguna solución en este hilo. –

Respuesta

13

¿Es posible almacenar estas expresiones regulares en una memoria 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 enganche en la implementación de C sre del motor de expresiones regulares de Python. Cualquier beneficio de rendimiento sería ampliamente superado por el tiempo y el esfuerzo requerido.

En primer lugar, ¿realmente ha perfilado 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 varias 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.

2

Tenga en cuenta que cada módulo lo inicia automáticamente una vez durante la vida de una aplicación, no importa 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ía estar bien.

-1

Es posible colocar cada regex (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.

+1

Aún debería compilarse la expresión regular, explícita o implícitamente, y esto lleva tiempo. –

0

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() 

entonces usted puede hacer una clase contenedora agradable que se encarga de automatizar el almacenamiento en caché para usted para que sea transparente para el usuario ... un ejercicio de izquierda a el lector.

+2

El módulo 'shelve' usa' pickle' internamente. Los patrones aún se volverían a compilar al cargarlos desde el estante. –

-1

Hum,

¿No balda uso pepinillo?

De todos modos, estoy de acuerdo con los informes 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 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 sabemos si lo hará, pero si no, buena suerte en que la investigación :-)

0

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

1

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, salpicarlo 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.

Cuestiones relacionadas