Strpos vs RegExp

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 !

Ça peut vous intéresser aussi


PHP vs Java

On vient de lever la polémique au taff et du ...


Roadsend PHP Compiler

Tien pendant que je suis encore là, j’ai testé ...


PHP Phar

Bon pendant qu’on y est, je vais vous présenter ...


PHP lol

Y’en a qui se marrent en PHP :) Regardez ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Gérald - 11/04/2008

La conclusion est donc d’utiliser preg lorsque les appels sont multiples ?

A partir de combien cela vaut t il le coup ?

Metal3d - 15/04/2008

Et bien à partir de 2 appels de la même regexp on a déjà un bon résultat.

Du moins d’après ce que je vois :)

Cany0n - 09/05/2010

Je vais faire les tests… Sur la regex, en l’ancrant (^) sur le motif, on pourrait avoir des meilleurs résultats, non? Je voulais aussi te dire que ton blog était sympa comme tout … Faut que je prenne le temps de dépouiller les articles et ca m’a m’a donné envie de regarder du côté de Copix du coup … Par contre, les zooms sur les articles, adsense etc sont saoulant. Merci pour tout ces bonnes choses…

Cany0n

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.