2009-03-11 17 views
18

Estoy escribiendo código PHP para analizar una cadena. Debe ser lo más rápido posible, ¿por qué las expresiones regulares son el camino a seguir? Tengo la corazonada de que las funciones de cadenas PHP son más caras, pero es solo una suposición. ¿Cuál es la verdad?¿Cuál es más eficiente, funciones de cadena PHP o expresiones regulares en PHP?

Aquí es específicamente lo que tengo que hacer con la cadena:

Coge la primera mitad (basado en la tercera posición de una subcadena "000000"), y comparar el hash para los próximos 20 bytes, tirar nada dejado .

Analice el 9º byte hasta el siguiente "000000" como una sola pieza de datos. Luego tome los siguientes 19 bytes después de eso, y divida eso en 8 (tira 1) y 8. Luego hago otras cosas que convierten esas dos cadenas de 8 bytes en fechas.

Así que ese es el tipo de cosas que necesito hacer.

Respuesta

16

Depende de su caso: si está tratando de hacer algo bastante básico (por ejemplo: buscar una cadena, reemplazar una subcadena con otra cosa), entonces las funciones de cadena regulares son el camino a seguir. Si desea hacer algo más complicado (por ejemplo, buscar direcciones IP), entonces las funciones Regex son definitivamente una mejor opción.

No he perfilado las expresiones regulares, así que no puedo decir que sean más rápidas en el tiempo de ejecución, pero les puedo decir que el tiempo extra dedicado a piratear el equivalente usando las funciones básicas no valdría la pena.


Editar con la nueva información en el PO:

Suena como si realmente se necesita para hacer una serie de operaciones de cadenas pequeñas aquí. Dado que cada uno individualmente es bastante básico, y dudo que puedas hacer todos esos pasos (o incluso un par de esos pasos) a la vez usando una expresión regular, iría con las funciones básicas:

Tome la primera mitad (basada en la tercera ubicación de una subcadena "000000") y compare su hash con los siguientes 20 bytes, descartando todo lo que quede.

Uso: strpos() y substr()
O: /$(.*?0{6}.*?0{6}.*?)0{6}/

Luego agarra los siguientes 19 bytes después de eso, y dividir que en 8 (cara o cruz 1) y 8.

Uso : substr() - (supongo que quiere decir 17 bytes aquí - 8 + 1 + 8)

$part1 = substr($myStr, $currPos, 8); 
$part2 = substr($myStr, $currPos + 9, 8); 
+1

Regexp son sorprendentemente eficiente. En general, no debería tener miedo de usarlos como la herramienta predeterminada. – troelskn

+1

@troelskn sin embargo, la documentación de php menciona que generalmente son más lentos que la función básica de php para la mayoría de las operaciones básicas, ya que no usan el motor de expresiones regulares. – T0xicCode

1

Las funciones de cadena nativas son mucho más rápidas. El beneficio de regexp es que puedes hacer prácticamente cualquier cosa con ellos.

6

Creo que hay un umbral a partir del cual una expresión regular es más rápida que una serie de llamadas de función de cadena PHP. De todos modos, depende mucho de lo que estás haciendo. Tienes que averiguar el saldo.

Ahora que ha editado su pregunta. Utilizaría las funciones de cadena para lo que estás tratando de lograr. strpos() y substr() es lo que viene a la mente a primera vista.

6

Creo que si quieres el mayor rendimiento, debes evitar la expresión regular ya que ayuda a minimizar el esfuerzo, pero no tendrá el mejor rendimiento ya que casi siempre puedes ajustar el código usando rutinas de cuerda a un problema específico y obtener un gran rendimiento impulso de eso. Pero para las rutinas de análisis simples que no se pueden optimizar mucho, aún puede usar expresiones regulares, ya que no hará una gran diferencia allí.

EDITAR: Para este problema específico que publicó, preferiría las operaciones de cadena, pero solo porque no sabría cómo hacerlo en expresiones regulares. Esto parece ser bastante directo, excepto por el hash, así que creo que las funciones de expresión regular/secuencia no marcarán una gran diferencia.

0

Depende de sus necesidades. La mayoría de las operaciones de expresión regular son más rápidas de lo que uno pensaría e incluso pueden superar las funciones de cadena incorporadas en ciertas operaciones triviales. Tenga en cuenta que tengo la biblioteca preg en mente, no la biblioteca regex integrada, que es bastante lenta.

4

Si lo que estás haciendo es razonable hacer usando funciones de cadena, deberías usarlas. Al igual que, si está determinando si se produce una cadena constante 'abc' en $value, definitivamente desea marcar strpos($value, 'abc') !== false, no preg_match('/abc/', $value). Si te encuentras haciendo muchas remodelaciones y transformaciones de cuerdas para lograr lo que hubieras hecho con una expresión regular, sin duda terminarás destruyendo tanto el rendimiento como la capacidad de mantenimiento.

Sin embargo, cuando te preocupes por la velocidad, no lo pienses, sincronízalo. El comando time es tu amigo.

4

En general, las funciones de cadena son más rápidas y las funciones de expresiones regulares son más flexibles.

Al igual que con cualquier otra cosa, los resultados pueden variar, la única manera de saberlo con certeza es probarlo en ambos sentidos y como punto de referencia.

2

Estoy de acuerdo con todo el mundo: las funciones de cadena son un poco más efectivas que las funciones de expresiones regulares. Sólo quería mostrar una pequeña prueba, que hice en el terminal como una prueba:

strpos():

$ time php -r '$i = 0; while($i++ < 1000000) strpos("abc", "a");' 

real 0m0.380s 
user 0m0.368s 
sys 0m0.008s 

preg_match():

$ time php -r '$i = 0; while($i++ < 1000000) preg_match("/abc/", "a");' 

real 0m0.441s 
user 0m0.432s 
sys 0m0.004s 
Cuestiones relacionadas