2010-09-28 14 views
6

Mir wurde gesagt, dass die Deaktivierung von Rückreferenzen in Perl die Performance verbessert (vorausgesetzt, Sie verwenden sie nicht), und wenn Sie keine Rückreferenzen verwenden, wird Perl dies selbst tun.Deaktivieren von Rückreferenzen in Perl

Jetzt habe ich ein Perl-Skript mit einer großen Anzahl von Regex in ihm und nur ein einziges verwendet eine Rückreferenzierung und ich möchte folgendes wissen:

  • Gegeben Ich habe eine sehr große Anzahl von regex (Nehmen wir an, der Großteil meiner Verarbeitungszeit ist Regex.) Bedeutet die Deaktivierung von Rückmeldungen eine signifikante Leistungsverbesserung? Oder gibt es Kriterien, anhand derer ich wissen kann, ob dies der Fall ist?
  • Gibt es eine Möglichkeit, ich kann Rückreferenzen einmal am Anfang deaktivieren und nur wieder aktivieren, wenn ich es brauche (ich weiß über (?:, aber ich möchte es nicht zu jeder Gruppierung hinzufügen)?
  • würde Scoping erlauben Perl für die Optimierung dieses Rückverweisverhaltens für mich (dh ändert sich sub oder eval, ob Perl Backreferencing für Dinge außerhalb davon deaktiviert)?
+1

* »unter der Annahme, dass die meiste meiner Bearbeitungszeit Regex ist« * O RLY? [Profil] (http://p3rl.org/Devel::NYTProf) um Ihre Annahmen zu entlarven. Ich wette, Ihr Programm ist nicht-trivial und * wird nicht die meiste Zeit in den Regexes verbringen. – daxim

Antwort

15

Durch die Verwendung von Klammern werden nur reguläre Ausdrücke, die sie verwenden, bestraft. Verwenden Sie sie daher an den Stellen, an denen Sie erfassen müssen, aber verwenden Sie nicht erfassende Paren (?:...), wenn Sie nur gruppieren müssen.

einem der globalen Anpaßvariablen Mit

$` $& $' 

erlegt eine Leistungseinbuße auf alle reguläre Ausdrücke, so vermeiden sie, wenn überhaupt möglich verwenden. (Aber wenn du es einmal getan hast, verrück dich! Du hast den Preis bereits bezahlt.) Es gibt keine Möglichkeit, das ein- und auszuschalten. Sobald Perl erkennt, dass sie überall verwendet werden (selbst in Modulen von Drittanbietern, die Sie verwenden können), ist die Funktion aktiviert.

Ab Perl 5.10.0 gibt es Alternativen für die globalen Übereinstimmungsvariablen, die nur reguläre Ausdrücke, die sie verwenden, benachteiligen. Wenn Sie den /p Modifikator zu einem bestimmten regulären Ausdruck hinzufügen können Sie dann

${^PREMATCH} ${^MATCH} ${^POSTMATCH} 

stattdessen verwenden.

2

Der einzige wirkliche Weg zu überprüfen ist, es selbst zu profilieren. Werfen Sie einen Blick auf das Benchmark Modul (es ist in Core Perl, so dass Sie es nicht installieren müssen). Richten Sie ein paar Benchmarks ein: eine, bei der Sie eine Funktion haben, die z. B. zehn Regexes ohne Rückreferenzen hat, und eine, die die gleiche zehn hat, aber eine davon verwendet Rückreferenzen.

Wenn Sie feststellen, dass die Rückreferenz - einschließlich Regex wirklich den Rest Ihrer Regexes verlangsamt, versuchen Sie vielleicht, das zu re-schreiben, um die Rückreferenz irgendwie nicht zu enthalten ...?

+0

Also, Benchmarking hilft mir, diese Entscheidung für diesen bestimmten Code zu treffen, aber ich hoffte auf einige Informationen, damit ich diese Entscheidung leichter treffen kann. Die Quintessenz hier ist, ich verstehe nicht eine Tonne über Deaktivieren/Aktivieren zurück Referenzieren und ich versuche, mehr Informationen zu bekommen, damit ich eine informierte Entscheidung treffen kann. – tzenes