Optimisez vos affichages avec echo

Attention ! Cet article s'adresse aux plus tatillons d'entre vous ! Je vais traiter ici d'une petite astuce pour optimiser l'utilisation de l'instruction echo en Php. Cette astuce consiste à rendre plus rapide l'affichage de chaînes concaténées en utilisant une syntaxe alternative. Si je vous ai prévenu que cela s'adressait aux optimisateurs fous, c'est qu'elle prendra une importance raisonnable sur un site à gros trafic par exemple, ou si vous affichez beaucoup de chaînes concaténées.

Si vous ne pensez pas faire partie de ces personnes, rien ne vous interdit de lire la suite pour votre culture ;).

Comment ?

Il existe une syntaxe particulière pour passer plusieurs paramètres à echo, que peu de gens connaissent. Elle ressemble beaucoup à un passage de paramètres à une fonction : les variables à afficher sont séparées par une virgule. C'est la solution que nous allons utiliser pour optimiser la sortie.

Prenons un exemple. Imaginons que nous voulions afficher un message de présentation d'une personne du style "Bonjour, je suis <prenom> <nom> et j'ai <age> ans". En excluant la syntaxe dont je viens de vous parler, on dispose de deux moyens pour afficher ce message :

$prenom = 'john';
$nom = 'doe';
$age = 12;

// avec simples quotes
echo 'Bonjour, je suis ' . $prenom . ' ' . $nom . ' et j\'ai ' . $age . ' ans.';

// avec doubles quotes
echo "Bonjour, je suis $prenom $nom et j'ai $age ans";

Rien d'époustouflant donc. Un détail tout de même, la première syntaxe est plus rapide que la seconde. Pourquoi ? Parce que dans la seconde, Php doit d'abord chercher si il y a des variables dans la chaîne avant de les remplacer par leurs valeurs, alors que dans la seconde, il suffit d'ajouter les chaînes dans l'ordre.

Maintenant, notre nouvelle syntaxe :

echo 'Bonjour, je suis ', $prenom, ' ', $nom, ' et j\'ai ', $age, ' ans.';

Vous avez dû le remarquer, c'est exactement la même chose qu'avec des simples quotes, sauf que les points sont remplacés par des virgules.

Pourquoi ?

Bonne question :P. En fait, la seule différence avec première forme, c'est qu'aucune concaténation n'est effectuée. Concrètement, voici un code équivalent à la première forme :

$chaine = 'Bonjour, je suis ';
$chaine = $chaine . $prenom;
$chaine = $chaine . ' ';
$chaine = $chaine . $nom;
$chaine = $chaine . ' et j\'ai ';
$chaine = $chaine . $age;
$chaine = $chaine . ' ans.';
echo $chaine;

Un peu lourd non ? J'ai volontairement décomposé au maximum les instructions, mais c'est exactement ce qui se passe. Voyons maintenant à quoi équivaut l'autre syntaxe, avec les virgules :

echo 'Bonjour, je suis ';
echo $prenom;
echo ' ';
echo $nom;
echo ' et j\'ai ';
echo $age;
echo ' ans.';

C'est déjà beaucoup mieux ! On ne le voit pas tout de suite, mais on vient d'économiser 7 affectations (=) et 6 concaténations (.) ;).

En bref

Finalement on peu classer les 3 méthodes par ordre de performances :

  • virgules :
    'Bonjour, je suis ', $prenom, ' ', $nom, ' et j\'ai ', $age, ' ans.'
  • simples quotes :
    'Bonjour, je suis ' . $prenom . ' ' . $nom . ' et j\'ai ' . $age . ' ans.'
  • doubles quotes :
    "Bonjour, je suis $prenom $nom et j'ai $age ans"

L'inconvénient, c'est que si on les classe par lisibilité, on change l'ordre :?. Alors à vous de choisir le meilleur compromis !

Edit du 13 août 2013

Il semble que depuis PHP 5.4, de grosses optimisations aient été faites sur la gestion des chaînes de caractères.

La méthode d'affichage la plus efficace est désormais l'interpolation de variables dans une chaîne entre doubles quotes. Vient ensuite la méthode des virgules, puis la concaténation.

Vous pouvez lancer et bidouiller ce petit script https://gist.github.com/felixgirault/6222639 pour vérifier ces résultats sur votre environnement ;).

Par , le .

Commentaires

  • Bonjour,
    J’ai fait un petit test et je n’arrive pas au même résultat:

    <?php
    function f1_virgule() {
    $a = '';
    for($i=0; $i<10000; ++$i) {
    echo $a,$i,"\n";
    }
    }
    function f2_point() {
    $a = '';
    for($i=0; $i time time_point => ' . ($time_virgule > $time_point);

    La virgule met toujours plus de temps (même en inversant l’ordre des fonctions)
    Soit la fonction echo a changé depuis votre article mais j’en doute, soit le raisonnement n’est pas bon.
    D’ailleurs en répétant vos deux exemples (avec concaténation et avec une suite d’echos) l’echo est moins performant que la concaténation, il vaut mieux faire :

    $chaine = 'Bonjour, je suis ';
    $chaine = $chaine . $prenom;
    $chaine = $chaine . ' ';
    $chaine = $chaine . $nom;
    $chaine = $chaine . ' et j\'ai ';
    $chaine = $chaine . $age;
    $chaine = $chaine . ' ans.';
    echo $chaine;

    que

    echo 'Bonjour, je suis ';
    echo $prenom;
    echo ' ';
    echo $nom;
    echo ' et j\'ai ';
    echo $age;
    echo ' ans.';

    Pour en revenir à la différence entre le point et la virgule, la virgule est un séparateur de paramètre de la fonction echo et visiblement, il met plus de temps à traiter plusieurs paramètres que de gérer la concaténation.

    En tout cas merci à vous car en faisant les tests, j’ai appris quelque chose.

    • Bonjour,
      Merci d’avoir passé du temps à vérifier tout ça !

      J’ai refait quelques tests de mon côté, et les résultats on étés tout aussi surprenants. J’en ai fait un gist si vous voulez jeter un oeil https://gist.github.com/felixgirault/6222639.

      Avec PHP < 5.4, je retrouve bien les résultats que j'exposais dans l'article, c'est à dire virgules > points > interpolation.
      Avec PHP >= 5.4 par contre, je tombe sur interpolation > virgules > points.

      Il est donc bien possible qu’un gros travail d’optimisation ait été fait sur le coeur de PHP !

      • Merci à vous d’avoir testé avec différentes versions de PHP.
        Bonne continuation. 🙂

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *