Cada vez que tengo que realizar operaciones simples de contención o reemplazo en strings, donde el término que estoy buscando es un valor fijo, me parece que si tomo mi entrada de muestra y hago algún perfil sobre ella, usando un compilado regular la expresión es casi * siempre más rápida que usar el método equivalente de la clase String.¿Por qué las expresiones regulares compiladas de C# son más rápidas que los métodos de cadenas equivalentes?
He intentado comparar una variedad de métodos (. hs
es el "pajar" para buscar, ndl
es la "aguja" para buscar, repl
es el valor de reposición regex
siempre se crea con la opción RegexOptions.Compiled
):
hs.Replace(ndl, repl)
vsregex.Replace(hs, repl)
hs.Contains(ndl)
vsregex.IsMatch(hs)
tengo se encuentran bastantes discusiones centradas en cuales de las dos técnicas son más rápidas (1, 2, 3, y un montón de otros), pero esas discusiones siempre parecen centrarse en:
- Utilice la versión de cadena para simples operaciones y expresiones regulares para operaciones complejas (que, desde una perspectiva de rendimiento en bruto, ni siquiera parece ser una buena idea), o
- Ejecute una prueba y compare los dos (y para pruebas equivalentes, la versión de expresiones regulares parece siempre funciona mejor).
No entiendo cómo puede ser este el caso: ¿cómo compara el motor de expresiones regex dos cadenas para las cadenas de subcadenas más rápido que la versión de cadena equivalente? Esto parece ser cierto para los espacios de búsqueda que son muy pequeños o muy grandes, o los términos de búsqueda que son pequeños o grandes, o si el término de búsqueda ocurre temprano o tarde en el espacio de búsqueda.
Entonces, ¿por qué son expresiones regulares más rápidas?
* De hecho, la única caso se ha logrado demostrar que la versión de cadena es más rápido que una expresión regular compilada está en la búsqueda de una cadena vacía! Cualquier otro caso, desde cadenas de caracteres individuales hasta cadenas muy largas, se procesa más rápido mediante una expresión regular compilada que con el método de cadena equivalente.
Actualización: añadido una cláusula para aclarar que estoy mirando a los casos en que el término de búsqueda se conoce en tiempo de compilación. Para operaciones dinámicas o de una sola vez, la sobrecarga de compilar la expresión regular tenderá a sesgar los resultados a favor de los métodos de cadena.
Creo que su mejor pregunta podría ser "Si la expresión regular es más rápida, ¿por qué los métodos String no usan solo expresiones regex?". De todos modos, mi única conjetura sería algo relacionado con que 1. la compilación de expresiones regulares requiere algo de tiempo adicional que no estás considerando, o 2. la compilación/procesamiento de expresiones regulares consume más memoria o algo así, y estás obteniendo una compensación de espacio-tiempo . – zebediah49
@ zebediah49 Creo que tienes razón en que mi pregunta te lleva a esa pregunta, pero estoy realmente interesado en por qué o cómo las expresiones regulares tienen un mejor rendimiento. –
¿De dónde vienen los votos cercanos? –