Noté que muchos desarrolladores están usando strstr y strpos para verificar la existencia de una subcadena. ¿Es uno de ellos el preferido y por qué?
Respuestas:
Desde el manual en línea de PHP :
Si solo desea determinar si una aguja en particular se encuentra dentro del pajar, use la función más rápida y menos intensiva en memoria
strpos()
.
if(strpos($haystack,$needle) !== false) { // do something }
, nunca if(strpos($haystack,$needle)) { // do bad things }
. strpos
devolverá 0 si $needle
está al principio de $haystack
, y 0 se considera igual a falso. (0 == false)
se evalúa como verdadero. (0 === false)
se evalúa como falso.
Aquí hay algunas otras respuestas (+ puntos de referencia) que obtuve a mi pregunta, que es casi la misma (no me di cuenta de la tuya al preguntar).
Mientras tanto también hice mi propia prueba de referencia, lo que me encontré 1000000 veces para cada funciones relevantes ( strstr()
, strpos()
, stristr()
y stripos()
).
Aquí está el código:
<?php
function getmicrotime() {
list($usec, $sec) = explode(" ", microtime());
return ((float) $usec + (float) $sec);
}
$mystring = 'blahblahblah';
$findme = 'bla';
echo 'strstr & strpos TEST:<pre>';
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) strstr($mystring, $findme);
$time_needed_strstr = getmicrotime() - $time_start;
echo 'strstr(): ',
round( $time_needed_strstr , 8 ). PHP_EOL;
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) stristr($mystring, $findme);
$time_needed_stristr = getmicrotime() - $time_start;
echo 'stristr(): ',
round( $time_needed_stristr , 8 ) . PHP_EOL;
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) strpos($mystring, $findme) !== false;
$time_needed_strpos = getmicrotime() - $time_start;
echo 'strpos() !== false: ',
round( $time_needed_strpos , 8 ) . PHP_EOL;
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) stripos($mystring, $findme) !== false;
$time_needed_stripos = getmicrotime() - $time_start;
echo 'stripos() !== false: ',
round( $time_needed_stripos , 8 ) . PHP_EOL;
echo PHP_EOL;
echo 'time_needed_stristr - time_needed_strstr: ',
round( $time_needed_stristr - $time_needed_strstr , 8) . PHP_EOL;
echo 'time_needed_stripos - time_needed_strpos: ',
round( $time_needed_stripos - $time_needed_strpos , 8) . PHP_EOL;
echo PHP_EOL;
echo 'time_needed_strstr - time_needed_strpos: ',
round( $time_needed_strstr - $time_needed_strpos , 8) . PHP_EOL;
echo 'time_needed_stristr - time_needed_stripos: ',
round( $time_needed_stristr - $time_needed_stripos , 8) . PHP_EOL;
echo '</pre>';
?>
Y aquí está el primer resultado, que muestra que strpos()
es el ganador :
strstr & strpos TEST:
strstr(): 2.39144707
stristr(): 3.65685797
strpos() !== false: 2.39055395
stripos() !== false: 3.54681897
time_needed_stristr - time_needed_strstr: 1.2654109
time_needed_stripos - time_needed_strpos: 1.15626502
time_needed_strstr - time_needed_strpos: 0.00089312
time_needed_stristr - time_needed_stripos: 0.110039
El siguiente es similar al primer resultado ( strpos()
es el ganador nuevamente):
strstr & strpos TEST:
strstr(): 2.39969015
stristr(): 3.60772395
strpos() !== false: 2.38610101
stripos() !== false: 3.34951186
time_needed_stristr - time_needed_strstr: 1.2080338
time_needed_stripos - time_needed_strpos: 0.96341085
time_needed_strstr - time_needed_strpos: 0.01358914
time_needed_stristr - time_needed_stripos: 0.25821209
A continuación se muestra otro, que es más interesante, porque en este caso, strstr()
es el ganador:
strstr & strpos TEST:
strstr(): 2.35499191
stristr(): 3.60589004
strpos() !== false: 2.37646604
stripos() !== false: 3.51773095
time_needed_stristr - time_needed_strstr: 1.25089812
time_needed_stripos - time_needed_strpos: 1.14126492
time_needed_strstr - time_needed_strpos: -0.02147412
time_needed_stristr - time_needed_stripos: 0.08815908
Esto significa que realmente puede depender de "circunstancias ambientales" , que a veces son difíciles de influir, y pueden cambiar el resultado de "tareas de microoptimización" como esta, en caso de que solo esté comprobando si una cadena existe en otra o no.
PERO creo que en la mayoría de los casos, strpos()
es el ganador en comparación constrstr()
.
Espero que esta prueba haya sido útil para alguien.
Muchos desarrolladores utilizan strpos
para la microoptimización fines de .
El uso strstr
también solo funciona si la cadena resultante no se puede interpretar como falsa en un contexto booleano.
strpos()
. Si quisiera la subcadena después de esa posición, llamo strstr()
.
strstr
hace más de lo necesario, por lo que es más lento.
strpos () detecta en qué parte del pajar se encuentra una aguja en particular. stristr () prueba si la aguja está en algún lugar del pajar
por lo tanto, strpos () es más rápido y consume menos memoria
una razón para strstr (): si su aguja está al comienzo de una cadena, strpos devuelve 0 (así que debe verificarlo con === falso)
strstr()
devuelve todo antes o después de la aguja, por lo que primero tiene que hacer el equivalente de strpos()
y luego crear esa subcadena . Ahí es donde está el impacto en el rendimiento.
Prefiero la strstr()
legibilidad y la codificación fácil ... strpos() !==false
es un poco confuso ...
strstr
es demasiado similar astrtr
strstr
también necesita una comparación estricta Ejemplo:('123450', '0')