2009-04-11 9 views
5

Sono confuso per la documentazione:Perché % () più veloce di () in Vim?

\%(\) Un modello racchiuso da sfuggiti parentesi. */\%(\)* */\%(**E53* Proprio come \(\), ma senza contare come una sottoespressione. Ciò consente a di utilizzare più gruppi ed è un po 'più veloce bit.

Qualcuno può spiegare il motivo della differenza? È a causa di backtracking o qualcos'altro?

risposta

11

Il commento "un po 'più veloce" è accurato in quanto c'è un po' meno di contabilità da fare, ma l'enfasi è su "un po '" piuttosto che su "più veloce". In sostanza, normalmente, il materiale corrispondente a \(pattern\) deve essere conservato in modo che sia possibile utilizzare \3 (per il numero appropriato) per fare riferimento ad esso nella sostituzione. La notazione % significa che vim non deve tenere traccia della corrispondenza, quindi sta facendo un po 'meno lavoro.


@SimpleQuestions chiede:

Che cosa si intende per "tenere traccia della partita"? In che modo influisce sulla velocità?

È possibile utilizzare parentesi di escape per "catturare" parti del modello abbinato. Ad esempio, supponiamo che stiamo giocando con le dichiarazioni di funzioni C semplici - non puntatori a funzioni o altre fonti di parentesi - allora potremmo avere un comando sostituto come il seguente:

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

Dato una linea di ingresso come ad esempio:

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

l'output sarà:?

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

(Perché si potrebbe desiderare di fare quel che sto immaginando che ho bisogno di avvolgere la funzione C simple_function in modo che possa essere chiamato da un linguaggio compilato in C che utilizza una convenzione di interfaccia diversa, basata su Informix 4GL, per essere precisi. Lo sto usando per fare un esempio - non perché hai davvero bisogno di sapere perché è stata una buona modifica.)

Ora, nell'esempio, lo \1 e \2 nel testo di sostituzione si riferiscono alle parti catturate dell'espressione regolare - il nome della funzione (una sequenza di caratteri alfanumerici che inizia con un carattere alfabetico - contando il carattere di sottolineatura come "alfabetico") e l'elenco di argomenti della funzione (tutto tra parentesi, ma senza includere le parentesi).

Se avessi usato la notazione \%(....\) attorno all'identificatore di funzione, allora \1 farebbe riferimento all'elenco degli argomenti e non ci sarebbe \2. Poiché vim non dovrebbe tenere traccia di una delle due parti acquisite dell'espressione regolare, ha meno impegni contabili rispetto a se dovesse tenere traccia di due parti acquisite. Ma, come ho detto, la differenza è minima; probabilmente non potresti mai misurarlo nella pratica.Ecco perché il manuale dice "consente più gruppi"; se avessi bisogno di raggruppare parti della tua espressione regolare ma non avessi bisogno di riferirti di nuovo, allora potresti lavorare con espressioni regolari più lunghe. Tuttavia, nel momento in cui hai più di 9 parti (catturate) memorizzate nell'espressione regolare, il tuo cervello di solito fa rotazioni e le tue dita commettono comunque degli errori, quindi di solito non ne vale la pena. Ma questo è, penso, l'argomento per usare la notazione \%(...\). Corrisponde alla notazione Perl (PCRE) '(?:...)' per un'espressione regolare senza acquisizione.

+0

Cosa intendi per "tenere traccia della partita"? In che modo influisce sulla velocità? –

+0

Ho effettivamente controllato - e funziona come dichiarato. E ho controllato la versione \% (\\) - non mostrata sopra - e anche quella ha funzionato. Accidenti! Non succede ogni volta che tutto funziona correttamente. Ero fiducioso del concetto ... ma è comunque una buona idea controllare la realtà. –

4

Ho chiesto in #Vim, se l'altro è più veloce a causa del backtracking. L'godlygeek utente ha risposto:

No, è più veloce perché la cosa che ha trovato non ha bisogno di essere strdup'ed - qualsiasi lavoro inutile è una cosa negativa per un file di sintassi.

Ha continuato:

[La velocità] dipende da quanto è grande la stringa è. Per 3 caratteri, lo è non importa molto, per 3000 it probabilmente lo fa. E ricorda che ha bisogno di essere strodato ogni volta che corrisponde a corrispondenze .... anche durante lo backtracking ... il che significa che anche i 3 caratteri potrebbero essere moltiplicati 1000 volte nel corso della corrispondenza una singola espressione regolare. - i file di sintassi sono in $ VIMRUNTIME/sintassi

Problemi correlati