35 votes

preg_match() vs strpos() pour la recherche de correspondance ?

Pour contrôle d'une valeur unique Lequel des deux est préféré et pourquoi ?

$string == 'The quick brown fox jumps over the lazy dog';

if(strpos($string, 'fox') !== false){
    // do the routine
}

# versus

if(preg_match('/fox/i', $string)){
    // do the routine
}

71voto

Je préférerais que le strpos plus preg_match car les expressions rationnelles sont généralement plus coûteuses à exécuter.

D'après la documentation officielle de php pour preg_match :

Ne pas utiliser preg_match() i si vous voulez seulement vérifier si une chaîne de caractères est est contenue dans une autre chaîne. [ ] strpos() o strstr() i seront plus rapides.

13voto

Michael Berkowski Points 137903

En cas de doute, il est préférable d'utiliser des points de repère !

Il est évident que nous aurions pu trouver un meilleur point de référence que celui-ci, mais il s'agit simplement de prouver que lorsque le système commence à s'étendre, il n'y a pas de problème, strpos() sera beaucoup plus rapide. (presque 2 fois plus rapide ici)

EDIT J'ai remarqué par la suite que l'expression rationnelle n'était pas sensible à la casse. Lorsque je l'ai exécutée à nouveau en utilisant stripos() pour une comparaison plus juste, le résultat est de 11 à 15, l'écart se réduit donc, mais il n'y a pas de différence entre les deux. preg_match() reste beaucoup plus lent.

$str = "the quick brown fox";
$start1 = time();
for ($i = 0; $i<10000000; $i++)
{
    if (strpos($str, 'fox') !== false)
    {
        //
    }
}
$end1 = time();
echo $end1 - $start1 . "\n";

$start2 = time();
for ($i = 0; $i<10000000; $i++)
{
    if (preg_match('/fox/i', $str))
    {
        //
    }
}
$end2 = time();
echo $end2 - $start2;

// Results:
strpos() = 8sec
preg_match() = 15sec

// Results both case-insensitive (stripos()):
stripos() = 11sec
preg_match() = 15sec

8voto

glortho Points 6288

N'utilisez jamais d'expressions régulières, sauf en cas d'absolue nécessité. Le surcoût lié au démarrage et au déploiement du moteur d'expressions régulières sur une chaîne de ce type est comparable à l'utilisation d'un marteau-piqueur au lieu d'un marteau ordinaire, d'une perceuse au lieu d'un tournevis.

La marge d'erreur est également plus grande avec les expressions rationnelles : chaînes non concordantes, résultats inattendus, etc. Restez-en à strpos, sauf si strpos n'est pas assez flexible.

5voto

ZJR Points 3342

Si vous utilisez déjà preg_match y preg_replace dans votre code, puis continuez à l'utiliser à nouveau. Pourquoi ?

  1. Performance. La plupart des frais généraux que ces fonctions ajoutent se situent dans le temps de chargement initial du moteur, si vous avez déjà payé ce prix, faites en sorte qu'il en vaille la peine.

  2. Lisibilité. strpos(...)!==false Bien que plus rapide, il s'agit d'un une horreur incroyable .

    Il s'agit de l'un des le plus laid constructions php.
    L'utilisation de == y false sont vraiment bizarres et semblent difficiles à analyser et fragiles à l'analyse. éditer.

Honte à l'équipe de base qui n'a pas défini d'alias comme strcontains() pour cela, il y a des années.
Maintenant, c'est bien trop tard de le faire, mais cela aurait été bien, à l'époque.

3voto

Mike Q Points 461

Le bon code est plus important

Donc, si vous pensez que ce genre de choses est important, gardez à l'esprit que c'est une constante dans Big O. En d'autres termes, les appels à la base de données, les activités On2 ou pire sont les seules choses qui comptent. Dans la plupart des cas, il est inutile de se préoccuper de ces commandes de bas niveau.

Cela ne veut pas dire que les constantes doivent être ignorées ; par exemple, j'ai remanié un code qui rassemblait des images car il le faisait une par une, chacune prenant 1 seconde, et cela a réduit la durée de 12 secondes à 1 seconde (en utilisant plusieurs requêtes curl). L'idée est que les commandes intégrées sont de bas niveau et que la structure du code est plus cruciale.

Le code ci-dessous effectue 10 millions d'appels de niveau inférieur et, comme vous pouvez le constater, les "économies" sont négligeables.

function prof_flag($str)
{
    global $prof_timing, $prof_names;
    $prof_timing[] = microtime(true);
    $prof_names[] = $str;
}

function prof_print()
{
    global $prof_timing, $prof_names;
    $size = count($prof_timing);
    for($i=0;$i<$size - 1; $i++)
{
    echo "<b>{$prof_names[$i]}</b><br>";
        echo sprintf("&nbsp;&nbsp;&nbsp;%f<br>",     $prof_timing[$i+1]-$prof_timing[$i]);
    }
    echo "<b>{$prof_names[$size-1]}</b><br>";
}

$l = 10000000;
$str = "the quick brown fox";
echo "<h3>Ran " .number_format($l,2) ." calls per command </h3>";

prof_flag("Start: stripos");

for ($i = 0; $i<$l; $i++)
    if (stripos($str, 'fox') !== false) {}

prof_flag("Start: preg_match");

for ($i = 0; $i<$l; $i++)
    if (preg_match('#fox#i', $str) === 1) {}

prof_flag("Finished");
prof_print();

La seule valeur de ce code est qu'il montre une façon cool d'enregistrer les temps d'exécution des choses lol

Ran 10,000,000.00 calls per command

Start: stripos
   2.217225
Start: preg_match
   3.788667
Start: ==
   0.511315
Start: ucwords lol
   2.112984
Finished

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X