PHP optimisations et astuces

03/06/2008

On vient d’en discuter avec Guillaume, et on est en train de le bloguer en même temps :) Tout d’abord pour vous parler de phpbench qui vous présente régulièrement des benchmarks de différentes méthodes PHP. Vous y découvrirez par exemple, et cela va être sujet à notre discussion juste après, que while (list(\$key,\$val) = each(\$array)) est largement plus rapide que foreach (\$array as \$key=>\$val). Ou encore que les if..elseif..else sont plus rapide que les switch/case… bref, allez lire la page et rafraichissez de temps en temps pour vous assurer des valeurs.

Mais revenons à notre discussion. Voyez ce petit bout de code: ` <?php //… while (list($key,$val) = each($array)){

} //… ?> `

A priori, ce code est très rapide, bien plus que foreach… mais avec un itérateur… ça ne marche pas. Vous avez deux solutions et il faudra vérifier laquelle sera la plus lente: soit revenir à foreach, soit faire: $array = iterator_to_array($array); Voir http://fr.php.net/manual/fr/function.iterator-to-array.php qui nous présente la méthode. Dans l’absolu, le code while list est utilisable… mais est-ce que la fonction iterator_to_array est si lente que cela serait plus lent qu’un foreach à l’ancienne ? Je ne sais pas, je vais faire le bench ce soir.

Une astuce qui est tombé juste dans notre conversation, c’est la méthode la plus simple de joindre des chaînes avec un séparateur.

Prenons l’exemple d’une série de lien dans un fil d’Ariane: “index | contact | links | about”. Si les valeurs proviennent d’un tableau, il peut être judicieux de simplement faire: $arian = implode(" | ",$array);

C’est simple rapide et efficace… mais lorsque nous passons dans un itérateur qui a des valeurs complexes à concaténer, cela devient vite fastidieux de vérifier si nous sommes dans le dernier élément et donc si il ne faut pas ajouter le dernier “pipe” à la fin. D’autant qu’il va falloir créer des liens, donc des balises… etc…

Imaginons cette structure: ` class link { public $url; public $title;
function __construct($url,$title){ $this->url = $url; $this->title = $title;
}

function create($url,$title){ return new self($url,$title); } } $array = array ( link::create(‘index.php’,‘Home’), link::create(‘index.php/contact’,‘Contact’), link::create(‘index.php/about’,‘About’), ); `

Nous avons donc un tableau d’objet. Voici la méthode la plus simple à mettre en place: // $flag = false; while (list($key,$val) = each($array)){ //ou un foreach... comme vous voulez if($flag){ //ne passera jamais par là lors de la première itération... echo " | "; } $flag = true; echo '<a href="'.$val->url.'">".$val->title.'</a>'; } //

Regardons comment cet algo fonctionne. Première itération, \$flag est à FALSE, donc on affiche pas de “pipe” (|). On écrit le premier lien et on continue. \$flag est passé à TRUE.\\ Seconde itération, on écrit le “pipe” puisque \$flag est vrai. Et on écrit le second lien.\\ Troisième et dernière itération, on écrit le “pipe”, et le troisième lien… et c’est fini.

Donc, pas de pipe en début et en fin de chaine, on a un “implode” manuel qui est nickel. Le fait d’utiliser un booléen, de tester une “vérité” au début et de ne pas faire de test sur la taille de \$array réduit fortement la charge.

Il faut penser à ce genre d’astuce le plus souvent possible. A la longue, après des milliers de lignes de code, cela rend votre site, votre application… bien plus rapide.

Merci Guillaume de m’avoir lancé sur le sujet ;)

Voir: http://apprendrelinux.blogspot.com/2008/06/afficher-un-lment-chaque-passage-dans.html

Ça peut vous intéresser aussi


Optimisations Copix PHP et Apache

Les temps de réponse… Dieu sait à quel point cela ...


Thread PHP dans Copix

Alors qu’on discutait sur le canal #fedora-fr de langages,...


Thread PHP dans Copix via HTTP

Dans le précédent post Thread PHP dans Copix, j’ai présenté la ...


Multiplexing ou Thread PHP sous Copix

Après moult développement en tout genre avec tests et montée ...

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 - 04/06/2008

Je crois qu’il y a mauvaise interprétation des résultats.

Le foreach est “plus” rapide que le while ($list () = each()) (dans tous les cas)

Metal3d - 04/06/2008

Alors là, on est deux à lire ton commentaire, à retourner sur phpbench… et à sauter au plafond…

Hier, tous les while étaient largement (mais alors largement) plus rapide…

Je vais certainement faire les bench moi même…

Guillaume - 04/06/2008

Et dire que tu avais réussi à me convaincre que le While était plus rapide … snif :)

Metal3d - 04/06/2008

Lol j’en étais convaincu aussi :p

Merci Gérald pour ton premier commentaire. Sans cela, j’aurai laissé trainé un mensonge sur mon blog… houuu la honte

Gérald - 04/06/2008

Ce qui m’a fait tiquer, c’est que j’avais très récemment joué a faire ces mesures de mon coté, et que j’étais tombé sur des conclusions à l’inverse de ce que tu présentais :-)

Je suis comme St Thomas, je ne crois que ce que je vois !

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.