2009-04-11 13 views
5

Ich bin verwirrt durch die docs:Warum ist % () schneller als () in Vim?

\%(\) Ein Muster von entkam Klammern. */\%(\)* */\%(**E53* Genau wie \(\), aber ohne zu zählen es als Unterausdruck. Dies ermöglicht mit mehr Gruppen und es ist ein wenig etwas schneller.

Kann jemand den Grund für den Unterschied erklären? Ist es wegen Backtracking oder etwas anderes?

Antwort

11

Der Kommentar "ein bisschen schneller" ist insofern korrekt, als etwas weniger Buchhaltung zu erledigen ist, aber die Betonung eher auf "wenig" als auf "schneller" liegt. Grundsätzlich muss normalerweise das Material \(pattern\) übereinstimmen, so dass Sie \3 (für die entsprechende Nummer) verwenden können, um darauf im Ersatz zu verweisen. Die % Schreibweise bedeutet, dass vim nicht das Spiel verfolgen muss - so macht es ein bisschen weniger Arbeit.


@SimpleQuestions fragt:

Was meinst du mit "Spur des Spiels halten"? Wie beeinflusst es die Geschwindigkeit?

Sie können ausgeblendete Klammern verwenden, um Teile des übereinstimmenden Musters zu "erfassen". Angenommen, wir mit einfachen C Funktionsdeklarationen gerade spielen - keine Zeiger auf Funktionen oder andere Quellen von Klammern - dann könnten wir einen Ersatz-Befehl wie die folgenden haben:

[email protected]\<\([a-zA-Z_][a-zA-Z_0-9]*\)(\([^)]*\))@xyz_\1(int nargs) /* \2 */@ 

eine Eingangsleitung wie Gegeben:

int simple_function(int a, char *b, double c) 

Der Ausgang wird sein:

int xyz_simple_function(int nargs) /* int a, char *b, double c */ 

(Warum können Sie das tun wollen ich stelle mir vor, dass ich die C-Funktion wickeln müssen simple_function so dass es von einer zu C kompilierten Sprache aufgerufen werden kann, die eine andere Schnittstellenkonvention verwendet - sie basiert auf Informix 4GL, um genau zu sein. Ich verwende es, um ein Beispiel zu bekommen - nicht weil Sie wirklich wissen müssen, warum es eine gute Änderung war.)

Jetzt beziehen sich die \1 und \2 im Ersetzungstext auf die erfassten Teile des regulären Ausdrucks - der Funktionsname (eine Folge von alphanumerischen Zeichen, die mit einem alphabetischen Zeichen beginnen - Unterstrich als 'alphabetisch' zählen) und die Funktionsargumentliste (alles zwischen den Klammern, jedoch ohne die Klammern).

Wenn ich die \%(....\) Notation um den Funktionsbezeichner verwendet hätte, würde sich \1 auf die Argumentliste beziehen und es gäbe kein \2. Da vim nicht einen der beiden erfassten Teile des regulären Ausdrucks verfolgen muss, ist die Buchführung etwas geringer, als wenn zwei erfasste Teile verfolgt werden müssten. Aber wie gesagt, der Unterschied ist winzig; Sie könnten es wahrscheinlich nie in der Praxis messen.Deshalb sagt das Handbuch "es erlaubt mehr Gruppen"; Wenn Sie Teile Ihres regulären Ausdrucks gruppieren müssen, aber nicht erneut darauf verweisen müssen, können Sie mit längeren regulären Ausdrücken arbeiten. Bis zu dem Zeitpunkt, an dem Sie mehr als 9 erinnerten (erfasste) Teile zum regulären Ausdruck haben, macht Ihr Gehirn normalerweise Drehungen und Ihre Finger werden trotzdem Fehler machen - also ist der Aufwand normalerweise nicht wert. Aber das ist, denke ich, das Argument für die Verwendung der Notation \%(...\). Es entspricht der Perl (PCRE) -Notation '(?:...)' für einen nicht erfassenden regulären Ausdruck.

+0

Was meinst du mit "verfolgen Sie das Spiel"? Wie beeinflusst es die Geschwindigkeit? –

+0

Ich habe tatsächlich überprüft - und es funktioniert wie gesagt. Und ich habe die \% (\\) Version überprüft - oben nicht gezeigt - und das hat auch funktioniert. Puh! Es passiert nicht jedes Mal, wenn alles korrekt funktioniert. Ich war von dem Konzept überzeugt ... aber es ist immer noch eine gute Idee, die Realität zu überprüfen. –

4

Ich fragte in #Vim, ob der andere wegen Backtracking schneller ist. Der Benutzer godlygeek beantwortet:

Nein, es ist schneller, weil die Sache, die angepasst ist muss nicht strdup'ed werden - jede unnötige Arbeit ist eine schlechte Sache für eine Syntaxdatei.

Er fuhr fort:

[Die Geschwindigkeit] hängt davon ab, wie groß die Zeichenfolge ist. Für 3 Zeichen ist es egal, für 3000 es wahrscheinlich tut. Und bedenken Sie, dass es muss jedes Mal, wenn es Übereinstimmungen .... einschließlich während Backtracking ... was bedeutet, dass sogar die 3 Zeichen 1000 mal im Laufe des Abgleichs straddup sein konnte ein einzelner Regex. - Die Syntax-Dateien sind in $ VIMRUNTIME/syntax

Verwandte Themen