2008-09-15 8 views
18

Jedes Mal, wenn eine Python-Datei importiert wird, die eine große Menge statischer regulärer Ausdrücke enthält, werden CPU-Zyklen ausgegeben in Speichern, um die Zeichenfolge in ihre repräsentativen Zustandsmaschinen zu kompilieren.Caching kompilierte Regex-Objekte in Python?

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

Frage: Ist es möglich, diese regulären Ausdrücke in einem Cache auf der Festplatte zu speichern, in einer vorkompilierte Weise auf jedem Import die regex Compilations ausführen zu vermeiden, dass?

Beiz- das Objekt einfach nicht die folgenden, verursacht Kompilierung sowieso passieren:

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

Und re Objekte sind 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

Leider hat meine Anwendung (900 reguläre Ausdrücke und Zählen) dieses Problem auch. Leider sehe ich in diesem Thread keine Lösung. –

Antwort

13

Ist es möglich, diese regulären Ausdrücke in einem Cache auf der Festplatte zu speichern, in einer vorkompilierte Weise auf jedem Import die regex Compilations ausführen zu vermeiden, dass?

nicht leicht. Sie müßten einen benutzerdefinierten Serializer schreiben, die die C sre Implementierung der Pythons Regex-Engine hakt in. Alle Leistungsvorteile würden durch den erforderlichen Zeit- und Arbeitsaufwand erheblich aufgewogen.

Zuerst müssen Sie den Code tatsächlich profiliert? Ich bezweifle, dass das Kompilieren von Regexen ein wesentlicher Teil der Laufzeit der Anwendung ist. Denken Sie daran, dass sie nur kompiliert werden, wenn das Modul zum ersten Mal in der aktuellen Ausführung importiert wird - danach werden das Modul und seine Attribute im Speicher zwischengespeichert.

Wenn Sie ein Programm haben, das im Grunde nur einmal erzeugt, eine Reihe von Regexes kompiliert und dann beendet, könnten Sie versuchen, es neu zu konstruieren, um mehrere Tests in einem Aufruf durchzuführen. Dann könnten Sie die Regexe wie oben wiederverwenden.

Schließlich konnte man die regulären Ausdrücke in C-basierten Zustandsmaschinen zusammenstellen und sie dann mit einem Erweiterungsmodul verknüpfen in. Während dies wahrscheinlich schwieriger zu verwalten wäre, würde es die Regex-Kompilierung vollständig aus Ihrer Anwendung entfernen.

2

Beachten Sie, dass jedes Modul selbst während der Laufzeit nur einmal initialisiert von eine App, egal wie oft Sie sie importieren. Wenn Sie also Ihre Ausdrücke im globalen Gültigkeitsbereich des Moduls kompilieren (dh nicht in einer Funktion), sollten Sie in Ordnung sein.

-1

Es ist möglich, jede Regex (oder Gruppe von Regexs) in eine separate Datei zu legen und dann die benötigte Datei dynamisch mit dem Imp-Modul zu importieren. Ich bezweifle, dass es sehr gut skaliert, aber es könnte sein, was Sie brauchen.

+1

Die Regex müsste noch explizit oder implizit kompiliert werden, und das braucht Zeit. –

0

Das shelve Modul einfach gut zu funktionieren scheint:


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

Sie können dann eine nette Wrapper-Klasse machen, die automatisch die Caching für Sie behandeln, so dass sie für den Benutzer transparent werden ... eine Übung gelassen der Leser.

+2

Das Modul 'shelve' verwendet intern' pickle'. Die Muster würden immer noch neu kompiliert werden, wenn sie aus dem Regal geladen werden. –

-1

Hum,

Hat ad acta nicht Gebrauch Gurke?

Wie dem auch sei, ich stimme mit den vorherigen anwsers. Da ein Modul nur einmal verarbeitet wird, bezweifle ich die Erstellung von Regexps.Und Python re Modul ist böse schnell, da es in C codiert ist :-)

Aber die gute Nachricht ist, dass Python eine nette Community hat, also bin ich sicher, dass Sie jemanden finden können, der gerade hackt, was Sie gerade brauchen.

Ich googelte 5 Sekunden und gefunden: http://home.gna.org/oomadness/en/cerealizer/index.html.

Sie wissen nicht, ob es es tun, aber wenn nicht, in dir viel Glück Forschung :-)

0

öffnen /usr/lib/python2.5/re.py und suchen Sie nach „def _compile“. Sie finden den internen Cache-Mechanismus von re.py.

1

Zunächst ist dies eine klare Einschränkung im Python Re-Modul. Es verursacht ein Limit, wie viel und wie groß reguläre Ausdrücke sinnvoll sind. Die Grenze ist größer bei langen laufenden Prozessen und kleiner bei kurzlebigen Prozessen wie Befehlszeilenanwendungen.

Vor einigen Jahren habe ich es mir angeschaut und es ist möglich, das Kompilierergebnis auszugraben, zu pikken und dann zu entpacken und wiederzuverwenden. Das Problem ist, dass es die Verwendung der sre.py-Interna erfordert und daher wahrscheinlich nicht in verschiedenen Python-Versionen funktioniert.

Ich möchte diese Art von Feature in meiner Toolbox haben. Ich würde auch gerne wissen, ob es separate Module gibt, die stattdessen verwendet werden könnten.