Ho notato che molti sviluppatori utilizzano sia strstr che strpos per verificare l'esistenza di una sottostringa. Uno di loro è preferito e perché?
Risposte:
Dal manuale in linea di PHP :
Se vuoi solo determinare se un particolare ago si trova all'interno del pagliaio, usa invece la funzione più veloce e con meno memoria
strpos()
.
if(strpos($haystack,$needle) !== false) { // do something }
, mai if(strpos($haystack,$needle)) { // do bad things }
. strpos
restituirà 0 se $needle
è all'inizio di $haystack
e 0 è considerato uguale a falso. (0 == false)
restituisce true. (0 === false)
restituisce false.
Ecco alcune altre risposte (+ benchmark) che ho ottenuto alla mia domanda, che è quasi la stessa (non avevo realizzato la tua quando me lo chiedevo).
Nel frattempo ho anche fatto il mio test di benchmark, che mi sono imbattuto 1000000 volte per ogni funzioni rilevanti ( strstr()
, strpos()
, stristr()
e stripos()
).
Ecco il codice:
<?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>';
?>
Ed ecco il primo output, che mostra che strpos()
è il vincitore :
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
Il prossimo è simile al primo output ( strpos()
è di nuovo il vincitore):
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
Di seguito è un altro, che è più interessante, perché in questo caso, strstr()
è il vincitore:
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
Ciò significa che può davvero dipendere da "circostanze ambientali" , che a volte sono difficili da influenzare, e può cambiare il risultato di "attività di microottimizzazione" come questa, nel caso in cui tu stia solo controllando se una stringa esiste o meno in un'altra.
MA penso che nella maggior parte dei casi, strpos()
è il vincitore rispetto a strstr()
.
Spero che questo test sia stato utile per qualcuno.
Molti sviluppatori usano strpos
per scopi di micro ottimizzazione .
L'uso funziona strstr
anche solo se la stringa risultante non può essere interpretata come falsa nel contesto booleano.
strpos()
. Se volevo la sottostringa dopo quella posizione, chiamo strstr()
.
strstr
fa più di quanto è richiesto, motivo per cui è più lento.
strpos () rileva dove giace un particolare ago nel pagliaio. stristr () verifica se l'ago si trova in un punto qualsiasi del pagliaio
quindi strpos () è più veloce e consuma meno memoria
un motivo per strstr (): se il tuo ago è all'inizio di una stringa, strpos restituisce 0 (quindi devi controllarlo con === false)
strstr()
restituisce tutto prima o dopo l'ago, quindi deve prima fare l'equivalente di strpos()
e poi creare quella sottostringa . Ecco dove si trova il successo in termini di prestazioni.
Preferisco strstr()
per leggibilità e facile codifica .. strpos() !==false
è un po 'confuso ..
strstr
è troppo simile astrtr
strstr
necessita anche di un confronto rigoroso Esempio:('123450', '0')