Strpos vs RegExp

Publié le 10/04/2008

Alors que je naviguait dans le source de Copix je me suis rendu compte qu’on utilisait à foison la fonction strpos permettant de savoir si l’on trouve un bout de texte dans une chaine. Etant fan de Perl, et donc adorant les expressions régulières, je me suis demandé si il ,‘était parfois pas plus judicieux d’utiliser la méthode preg_match.

J’ai donc créé une petit bench très simple qui vise à voir le temps de traitement sur une portion de code de CopixUrl. voici le code:

` <?php $pDest = “https://toto";

//change this $iter = 1;

$mtime = microtime(); $mtime = explode(” “,$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime;

for ($i=0;$i<$iter;$i++){ if (strpos ($pDest, ‘http://‘) === 0 || strpos ($pDest, ‘https://‘) === 0 || strpos ($pDest, ‘ftp://‘) === 0 || strpos ($pDest, ‘ftps://‘) ) { //echo “ok “; } } $mtime = microtime(); $mtime = explode(” “,$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $totaltime = ($endtime - $starttime); echo “”.$totaltime.” seconds”; echo “ “;

$mtime = microtime(); $mtime = explode(” “,$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime;

for ($i=0;$i<$iter;$i++){ if (preg_match(‘;^((http(s)?://)|(ftp(s)?://));‘,$pDest)){ //echo “ok 2 “; } } $mtime = microtime(); $mtime = explode(” “,$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $totaltime = ($endtime - $starttime); echo “”.$totaltime.” seconds”; echo “ “; ?> `

Avec \$iter à 1, il est clair que la méthode strpos est plus rapide de quelques milisecondes. Multipliez le nombre de fois où nous l’utilisons, cela peut faire gagner du temps. Sauf… sauf dans le cas où le même test est effectué plus d’une fois. Pour preuve, passez \$iter à 2, puis 10, puis 1000 ou encore 150000… vous allez voir que très vite la méthode utilisant les regexp va aller 2 fois plus vite.

Tout réside dans le fonctionnement des regexp et en particulier le moteur PCRE inclu dans PHP. L’idée étant qu’une regexp doit se compiler puis s’exécuter pour fonctionner, Donc pour une seule itération cela prend plus de temps, puis pour 2 la regexp est déjà compilée, et donc elle va plus vite… pour 15000 itérations, PCRE est imbattable :)

Comme PCRE va bientôt être compilé nativement dans PHP 6, pensez à cela, c’est parfois pas grand chose, mais ça en vaut la peine avec un framework.

Voici mon résultat avec \$iter à 1.500.000:

[patachou@localhost ~]$ php /tmp/test.php 
9.5994889736176 seconds
6.2041039466858 seconds

C’est plus de 3 secondes de gagner… soit plus de 30% par rapport à la méthode strpos. Croyez moi, c’est beaucoup !

comments powered by Disqus