PHP optimisations et astuces

Tags:: php :: copix :: bench

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

Utilisez le code barre pour ouvrir le ticket dans votre mobile:
This ticket on you mobile
1 Mercredi 04 Juin 2008 08:54:43, Gérald

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)

2 Mercredi 04 Juin 2008 10:21:28, Metal3d

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...

3 Mercredi 04 Juin 2008 10:22:42, Metal3d

Solution trouvé par Guillaume, l'auteur de phpbench à écrit cela dans la nuit:

"Given that the previous version of the tests have been very controvercial and incorrect, I must appologise for forgetting to implement the reset() function to allow the while() loops to start from the beginning instead of the end. Thanks to Anthony Bush for spotting this out."

Voilà qui est dit

4 Mercredi 04 Juin 2008 10:26:13, Guillaume

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

5 Mercredi 04 Juin 2008 10:27:37, Metal3d

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

6 Mercredi 04 Juin 2008 10:33:40, Gérald

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
Veuillez répondre à la question suivante : Taper "geek" sans les guillemets

Trackbacks

Pour ajouter un trackback (retrolien) sur ce ticket, utilisez cette adresse: http://www.metal3d.org/index.php/trackback/default/tb?id=blog%2F81

Tags

Blog Copix Communication PC Config Fedora Vidéo Humour Autre Web Materiel Informatique PHP Développement Mootools HTML Linux WEB IE CSS Vista Microsoft Sympa XHTML Quizz Widget Klik CWE Voeux Bonne année Musique CCRMA Son Audio MAO Reconnaissance vocale Windows Mac Compiz MacOS Mysql Sun Base de données BD Screenlets Screenlet RPM compiz Ubuntu Live FireFox Derambarsh Facebook media informations Sécurité javascript SSH Commande Marketing concours ipod wii QT Trooltech Nokia Libre Logiciels GPL Attali Gnome Dock Compiler Bench undelete reiserfs recovery recover Thread Serveur Optimisation Server Apache Album RSS Flash Air XML Firefox Blender Opensource Orange Internet LiveBox Animaux Droits Logiciels Libres Google Loi RBS netcat Bash Téléphone Spam 3D NIDIA Standards Widgets Merise UML Streaming Developpement Perl MySQL Firewall Parfeu Bayes Novell Réseau Python LVS Salon FTP Dedibox Chrome Administration IRC Gentoo troll video Nouveauté Finance Etudiant spéctacle OpenOffice Javascript Java Info Eclpise ATI design mootools KDE Bureau Design GNU C Pages Jaunes Fun Bijoux Art mail Admin vmware fedora linux VirtualBox VMWare Qemu KVM vim Grep Fglrx Webkit GTK google web JQuery Coup de gueule coup de gueule Lois SVG Raycaster Canvas Hadopi Desktop Jeux Les Sims développement astuces Screen firefox Mobile Safaru Wine bash commande astuce Wave ooc C++ C# Netbook Hercules Bureautique Twitter Safari W3C chrome kazehakaze midori navigateur gecko webkit Links Liens Pyhon Nouvelles Metal Perso Conférence JDLL PCC Roadsend OOC News Acteur Cinéma Chanteur Seven windows orthographe pcc php jdll Slide Application mysql Html twitter python screen curses SVN Android Gphone iPhone OpenGL MindMap Projet Javascrtip Ajax Guitare Tab Tablature JSON firebug Chromium Iphone Titanium music sound android ogg ogv streaming Arkyne svn subversion gnome VLC Tv encoder ffmpeg Cryptage apple microsoft HTML5 Max Apple code youtube quvi git uzbl webgl chromium

  Catalogue professionnel de musique libre


  • twitter entries...
follow me on Twitter

Valid XHTML 1.0 Strict

tumblr visitor