vendredi 20 juin 2008

PHP et les tableaux

Posté par Nicolas (lien permanent)

Aujourd'hui, j'ai eu besoin de trouver la méthode la plus rapide pour chercher une valeur dans un tableau en PHP 5.2.3. Ça paraît super simple dit comme ça, mais le PHP est loin d'être le langage le moins verbeux... Je recherche donc la valeur «lol» dans le tableau suivant :
1, 'ceci est une chaîne de caractères', 2, 'true', 3, 'ceci est une autre chaîne', 4, 5, 'lol..?', 6, 'false', 7, 'lol', 8, 1564891215, 10, ' ', 11, 'fin'
Rien que pour rechercher cette valeur dans le tableau, j'ai réussi à trouver 8 méthodes différentes.
  • Boucler sur les valeurs du tableau avec un foreach($array as &$val) et comparer les valeurs une à une.
  • Passer toutes les valeurs du tableau en clés via array_combine() et faire un array_key_exists($value, $array) dessus.
  • Passer toutes les valeurs du tableau en clés via un array_combine() et faire un isset($array[$value]).
  • Remettre les valeurs en clés mais via array_flip($array) et retenter un array_key_exists($value, $array) dessus.
  • Remettre encore les valeurs en clés via array_flip($array) et tenter un isset($array[$value]) dessus.
  • Effectuer l'intersection du tableau $array et de array($value) et regarder s'il y a une concordance.
  • Utiliser la fonction in_array($value, $array) dédiée à ça de PHP, mais réputée lente.
  • Utiliser la fonction array_search($value, $array) dédiée à ça de PHP, mais réputée lente.
Les résultats sont étonnants et parlent d'eux même :
100000 iterations :
0.3730 — foreach($array as &$val)
1.0708 — array_key_exists($value, array_combine($array, array_fill(...)))
1.0194 — isset(array_combine($array, array_fill(...))[$value])
0.8494 — array_key_exists($value, array_flip($array))
0.7558 — isset(array_flip($array)[$value])
4.2376 — count(array_intersect($array, array($value))) > 0
0.2198 — in_array($value, $array)
0.1967 — array_search($value, $array) !== false
Alors que les fonctions in_array() et array_search() sont réputées lentes, il s'avère que ce sont finalement bel et bien les plus rapides ici. Je me suis alors demandé si elles feraient toujours aussi bien avec des tableaux plus grands, j'ai donc testé un tableau de 1000 entiers au hasard, et voilà :
1000 iterations each :
00.2598 — foreach($array as &$val)
00.4319 — array_key_exists($value, array_combine($array, array_fill(...)))
00.4293 — isset(array_combine($array, array_fill(...))[$value])
00.3286 — array_key_exists($value, array_flip($array ))
00.3351 — isset(array_flip($array)[$value])
16.9131 — count(array_intersect($array, array($value))) > 0
00.0826 — in_array($value, $array)
00.0772 — array_search($value, $array) !== false
J'ai ensuite essayé 10000 entiers, puis 1000 chaînes de caractères, et au final, in_array() et array_search() sont toujours plus rapides. Je me demande si je n'ai pas fait quelque chose de travers. En tout cas, ces résultats sont à méditer.

Commentaires :

Le 21/6/08, Anonymous Anonyme a dit :

PHP entier est à méditer :
http://toykeeper.net/soapbox/php_problems/

Le 22/6/08, Blogger Nicolas a dit :

Oh oui, je crois que tout bon programmeur PHP connait malheureusement ce site.
Heureusement que le langage reste ultra souple et facile à mettre en oeuvre.

Enregistrer un commentaire

Liens vers ce billet:

Créer un lien

Retour à l'index

Images