2009-04-11 36 views
5

Estoy confundido por los documentos:¿Por qué % () es más rápido que () en Vim?

\%(\) Un patrón encerrado por escapado paréntesis. */\%(\)* */\%(**E53* Al igual que \(\), pero sin contar como una sub-expresión. Esto permite usando más grupos y es un poco más rápido.

¿Alguien puede explicar el motivo de la diferencia? ¿Es por retroceder o algo más?

Respuesta

11

El comentario 'un poco más rápido' es preciso ya que hay un poco menos de contabilidad por hacer, pero el énfasis está en 'poco' en lugar de 'más rápido'. Básicamente, normalmente, el material emparejado por \(pattern\) debe mantenerse para que pueda usar \3 (para el número apropiado) para referirse a él en el reemplazo. La notación % significa que vim no tiene que hacer un seguimiento de la coincidencia, por lo que está haciendo un poco menos de trabajo.


@SimpleQuestions pregunta:

¿Qué quiere decir con "no perder de vista el partido"? ¿Cómo afecta la velocidad?

Puede usar paréntesis escapados para 'capturar' partes del patrón combinado. Por ejemplo, supongamos que estamos jugando con las simples declaraciones de funciones C - no hay punteros a funciones u otras fuentes de paréntesis, - entonces podríamos tener un sustituto de comandos como la siguiente:

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

Dada una línea de entrada, tales como:

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

la salida será:?

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

(¿Por qué querría hacer eso me estoy imaginando que necesito para envolver la función C simple_function para que pueda ser llamado desde un lenguaje compilado a C que usa una convención de interfaz diferente, está basado en Informix 4GL, para ser precisos. Lo estoy usando para obtener un ejemplo, no porque realmente necesite saber por qué fue un buen cambio.)

Ahora, en el ejemplo, \1 y \2 en el texto de reemplazo se refieren a las piezas capturadas de la expresión regular - el nombre de la función (una secuencia de caracteres alfanuméricos que comienzan con un carácter alfabético - contando el guión bajo como 'alfabético') y la lista de argumentos de la función (todo entre paréntesis, pero sin incluir los paréntesis).

Si hubiera utilizado la notación \%(....\) alrededor del identificador de función, entonces \1 se referiría a la lista de argumentos y no habría \2. Debido a que vim no tendría que hacer un seguimiento de una de las dos partes capturadas de la expresión regular, tiene menos contabilidad que hacer que si tuviera que hacer un seguimiento de dos partes capturadas. Pero, como dije, la diferencia es pequeña; probablemente nunca podrías medirlo en la práctica.Es por eso que el manual dice 'permite más grupos'; si necesita agrupar partes de su expresión regular pero no necesita referirse a ellas nuevamente, entonces podría trabajar con expresiones regulares más largas. Sin embargo, para el momento en que tengas más de 9 partes recordadas (capturadas) en la expresión regular, tu cerebro generalmente hace giros y tus dedos cometerán errores de todos modos, por lo que el esfuerzo no suele valer la pena. Pero ese es, creo, el argumento para usar la notación \%(...\). Coincide con la notación Perl (PCRE) '(?:...)' para una expresión regular no captadora.

+0

¿Qué quiere decir con "realizar un seguimiento de la coincidencia"? ¿Cómo afecta la velocidad? –

+0

En realidad lo he comprobado, y funciona como se indica. Y revisé la versión \% (\\) - que no se muestra arriba - y eso también funcionó. ¡Uf! No sucede cada vez que todo funciona correctamente. Estaba seguro del concepto ... pero sigue siendo una buena idea verificar la realidad. –

4

Pregunté en #Vim, si el otro es más rápido debido al retroceso. El godlygeek usuario ha contestado:

No, es más rápido porque lo que está emparejado no tiene por qué ser strdup'ed - cualquier trabajo innecesario es una mala cosa para un archivo de sintaxis.

Y continuó:

[La velocidad] depende de lo grande que es la cadena . Para 3 caracteres, no importa mucho, para 3000 es probable que . Y tenga en cuenta que necesita ser ampliado cada vez que coincide ... incluso durante retrocediendo ... lo que significa que incluso los 3 caracteres podrían ser strdup'ed 1000 veces en el transcurso de la correspondencia una sola expresión regular. - los archivos de sintaxis están en $ VIMRUNTIME/sintaxis

Cuestiones relacionadas