Gibt es eine Engine für reguläre Ausdrücke, die Just-in-Time-Kompilierung während der Analyse von Regex-Mustern durchführt und beim Abgleich / Ersetzen von Texten verwendet? Oder wo kann ich JIT für i386 oder x64 Architektur erlernen?
Ich habe kürzlich versucht, die integrierte Regex-Engine von Python zu bewerten verglichen mit normalem C-Code mit ca. 10 MB Daten.
Ich fand, dass es für einen einfachen Austausch (zum Beispiel ab
bis zzz
) relativ schnell ist: nur 2 bis 3 mal langsamer als C.
Aber für [a-z]c
hat es etwa 5 bis 8 mal so viel Zeit gekostet wie C.
Und mit der Gruppierung (z. B. ([a-z])(c)
bis AABB
) dauerte es 20 bis 40 mal so viel Zeit wie C.
Es ist noch kein Just-In-Time-Kompilieren, aber ich denke, wenn ich Just-In-Time kompilieren könnte, könnte es viel mehr beschleunigen.
PS: Ich verwende Profiling für jedes Regex-Muster während des Kompilierens von Mustern,
Beispiel: Profil 1 für einfache wie ab
, Profil 2 für Bereich [a-z]c
, Profil 3 mit Gruppierung ([a-z])(c)
, jedes Profil hat separate Codes, so dass keine zusätzlichen Kosten für das Vergleichen und Ersetzen einfacher Muster erforderlich sind.
Ich habe es mit Psyco versucht, und es verbessert die Geschwindigkeit nicht so sehr. Kann sein, weil ich Text gegen große Daten ersetze, nicht viele Schleifen.
Wenn ich nicht falsch liege, läuft Pythons re.sub
nativ, denke ich, also kann Pysco die Geschwindigkeit nicht so sehr verbessern.
Ich habe versucht, mit Boost Regex in Python eingewickelt, aber es ist noch langsamer als Pythons Regex, so scheint es der Flaschenhals in Python String-Verarbeitung und Jan Goyvaerts hat mich auch darauf in der Antwort hingewiesen.
Ich möchte das Regex-Muster ab[a-z]c
in Maschinencode umwandeln, wie den folgenden äquivalenten C-Code ( *s
zeigt auf 10MB lange Texte):
Irgendwelche Ideen?
Die einzige Regex-Engine, von der ich weiß, dass sie reguläre Ausdrücke in ausführbaren Code kompilieren kann, ist diejenige in .NET, wenn Sie RegexOptions.Compiled übergeben. Das bewirkt, dass die Regex-Klasse MSIL ausgibt, die wie jeder andere .NET-Code JITt werden kann.
Ob die .NET-Regex-Engine schneller als andere ist, ist eine ganz andere Sache. Beim Suchen und Ersetzen mithilfe relativ einfacher regulärer Ausdrücke in großen Datensätzen wird die Verarbeitung von Strings weitaus wichtiger. .NET-Zeichenfolgen sind unveränderlich, und vieles hängt davon ab, wie oft die Zeichenfolge neu zugewiesen werden muss.
Die Handcodierung der Operation wird immer schneller sein, da der Code nicht gleichwertig ist. Der Regex-Code behält bestimmte Informationen über die Regex-Übereinstimmung und die Erfassungsgruppen bei, die Ihr Code nicht hat. In den meisten Situationen ist die zusätzliche Zeit, die Sie mit der manuellen Codierung des Suchen-und-Ersetzen statt mit einem Regex verbringen, nicht der Mühe wert, insbesondere wenn Sie berücksichtigen, dass die Umstellung auf einen anderen Regex trivial ist, wenn sich Ihre Anforderungen ändern, während Sie neu schreiben Das Suchen und Ersetzen mit prozeduralem Code erfordert viel mehr Zeit.
Nach meiner Erfahrung ist PCRE einer der schnellsten Regex-Engines überhaupt. Es enthält jedoch kein vorgefertigtes Suchen und Ersetzen.
Ich sehe es nicht in Ihrer Frage, also frage ich: Haben Sie mit vorkompilierten regulären Ausdrücken getestet, z. "re.compile (pattern)" ??
Da kompilierte Regexe schneller sein sollten. OK, es ist nicht JIT, aber die meiste Zeit geht es Ihnen gut mit einfach vorkompilierten!
Siehe hier:
Eine andere Idee: Wenn Sie eine Bibliothek (in C) haben, die optimaler ist als das Python-Regex-Modul oder Just-in-Time-Kompilierung von Regexes, dann könnten Sie Ihr eigenes Regex-Modul für Python schreiben, das nur umläuft Ihre C-Bibliothek.
Das ist natürlich etwas mehr Arbeit und nur zu empfehlen, wenn Sie wirklich, wirklich die Geschwindigkeit brauchen.
Du könntest auch Cython ausprobieren (persönlich habe ich es noch nicht benutzt, aber es hört sich ziemlich gut an), die Aufgabe des Wrappings zu erledigen .
Soweit ich dein Problem jetzt verstehe, ist das Python-Umfeld nicht dein Problem (also bezweifle ich, ob Psyco helfen wird) - auch die Vorbereitung des Regex-Laufes ist nicht dein Problem, sondern der Lauf selbst muss top sein -Geschwindigkeit. Das hängt natürlich von der verwendeten Bibliothek ab und davon, wie gut sie mit großen Strings umgehen kann. Ich würde denken, dass die Standard-Python-Regex-Lib nicht für so lange Strings und Top-of-the-Notch-Geschwindigkeit optimiert ist.
Wenn ich Sie also richtig verstehe, verwenden Sie eine Programmiersprache, die standardmäßig keine Just-in-Time-Kompilierung durchführt und jetzt nach einer Regex-Bibliothek sucht, die genau das tut?
Ich denke, Sie sollten Ihren gesamten Python-Code unter Verwendung von z. Psyco
auch hier diskutiert:
Ist es machbar, Python mit Maschinencode zu kompilieren?
und hier:
Ist es möglich, Python nativ zu kompilieren? (über pyc Bytecode hinaus)?
Wenn diese Lösungen entweder nicht funktionieren oder noch nicht schnell genug sind und Sie den Rest Ihrer Anwendung unbedingt in Python schreiben wollen, gibt es die boost python c ++ - Bibliothek:
Die boost.python-Bibliothek ermöglicht die vollständige Interoperabilität zwischen Python und C ++. Dann könnten Sie den regex-Matcher von boost.regex c ++ verwenden:
Ich könnte mich irren, aber ich glaube, dass Pythons Regex-Modul in C ist, also würde jeder Vorschlag, Python zu kompilieren (wie mit Psycho), keinen großen Unterschied machen - was Sie eigentlich vergleichen, ist die Leistung eines C Regex-Bibliothek (Python) mit einer anderen (egal welche Bibliothek Sie verwenden).
Thompson hatte 1968 in den Mitteilungen der ACM eine Arbeit veröffentlicht, die einen funktionierenden JIT-Compiler für reguläre Ausdrücke in IBM 7094-Code beschrieb. Ich weiß nicht, welche Sprache (n) er benutzt hat; Fortran oder LISP wären die offensichtlichen Verdächtigen, wobei LISP besonders verdächtig ist, da es bereits ein JIT-Kompilieren aufwies.
Die Engine für reguläre Ausdrücke in Firefox kompiliert einige (nicht alle!) reguläre Ausdrücke zum Maschinencode. Ich glaube Safari und Chrome auch.