PHP et Optimisation

Introduction

L'optimisation relative aux scripts PHP n'est que très rarement évoquée, car on a le sentiment que PHP est déjà très rapide. Or souvent il est important d'économiser la puissance du serveur hébergeant votre site, non seulement pour délivrer plus rapidement les pages à vos visiteurs, mais aussi pour en accueillir un plus grand nombre simultanément. Je vous propose quelques benchmarks réalisés sous Apache 2.0 avec PHP 4.3.1 en module pour illustrer quelques points propres à PHP qui pourront changer vos habitudes et améliorer la vitesse d'exécution de vos scripts.

Notez que MySQL n'est pas abordé ici, mais qu'il est souvent le facteur le plus déterminant dans la rapidité d'exécution des scripts faisant appel à cette base de données. J'en traiterai prochainement dans un autre article. Les benchmarks présentés ci-dessous sont indicatifs. Vous pouvez obtenir des temps plus ou moins variables sur votre machine avec une configuration matérielle différente.

Méthode de benchmark

Pour obtenir une plus grande fiabilité des résultats, j'ai exécuté les bouts de codes à comparer entre 1000 et 10000 fois dans le même script grâce à l'itération d'un simple for. J'ai utilisé la fonction microtime() (manuel) de PHP pour mesurer les temps d'exécution de chaque portion de code, avant et après. Une soustraction entre les deux valeurs et une division par le nombre d'itérations permet de déterminer le temps pris pour chaque instruction mais ce n'est pas ce qui est analysé ici, les différences n'étant que de quelques microsecondes. L'optimisation n'est intéressante qu'à grande échelle et les graphiques présentés ci-après permettent de distinguer le rapport entre les deux temps mesurés. Les valeurs indiquées les plus petites correspondent aux instructions les plus performantes.

Voici une fonction qui vous permettra de reproduire ces tests chez vous (elle retourne un temps en secondes)
function getmicrotime() {
   $mtime = microtime();
   $mtime = explode(" ",$mtime);
   $mtime = $mtime[1] + $mtime[0];
   return ($mtime);
}

Double quotes VS quotes simples

L'usage de double quotes (") est plus courant que celui des simples ('), pour la manipulation de chaînes de caractères. Tout simplement par habitude ou même par facilité d'utilisation car en effet leur différence majeure est l'interprétation des variables potentielles qu'elles peuvent contenir. On peut dire que "I'm a lama" est semblable à 'I\'m a lama' (ne pas oublier d'échapper les quotes à l'aide de l'antislash).

' vs ''Pas de surprise, avec des bouts de texte classiques, aucune différence n'est remarquable entre les deux tests. On peut dire que pour du texte banal les deux solutions sont équivalentes.

Par contre dès qu'un signe dollar ($) y figure, celui-ci est analysé dans le cas des double quotes, pour trouver une variable qui lui correspond et remplacer l'occurence par sa valeur. Ceci induit un temps de latence supplémentaire car le parseur PHP doit effectuer deux à trois fois plus d'opérations par rapport aux quotes simples pour lesquelles aucune analyse n'est faite.

' vs ''L'introduction d'un dollar ($) dans les chaînes ne perturbe pas les quotes simples mais ralentit logiquement les double quotes. Sachant que les chaînes de caractères sont l'élément principal manipulé par PHP, surtout au niveau de la sortie du code HTML, on peut voir quel est l'intérêt d'utiliser des quotes simples 4 fois plus rapides.

' vs ''On teste ici l'affichage d'une chaîne de texte contenant une variable, qui est concaténée pour les quotes simples afin que le résultat final soit équivalent des deux côtés (sinon '$test' est affiché tel quel).
Les quotes simples sortent gagnantes avec un gain de temps de 100%.

Conclusion : Vous serez toujours gagnant si vous utilisez les quotes simples, avec concaténation (.) des variables si nécessaire.

<? ou <?php

<? ou <?phpIl y a deux façons de débuter un script : <? ou <?php. Sémantiquement la deuxième solution est conseillée. Certains disent qu'elle est aussi plus rapide car le couple serveur/module PHP sait immédiatement qu'il a affaire à du code PHP. Or on remarque qu'il n'en est rien : les deux façons de faire sont équivalentes. Par contre si vous envisagez d'utiliser PHP dans du code XML ou XHTML, il est nécessaire de préciser <?php (manuel).

Conclusion : à vous de décider :)

echo VS print

echo vs printLes deux principales fonctions de sortie (ie : d'affichage de texte) sont echo (manuel) et print (manuel). On peut aussi tout comme en C, utiliser printf (manuel) mais cette fonction est de toute manière plus lente à cause de ses masques de sortie. En réalité echo n'est qu'une structure du langage et son utilisation se fait sans les parenthèses communes aux fonctions.

echo vs printecho a l'air plus rapide sur des petits bouts de texte.

echo vs printprint reprend un petit avantage sur des portions plus grandes contenant des variables, mais c'est négligeable.

echo vs printCeci est le point le plus intéressant : print se révèle très faible sur des chaînes longues et confirme la réputation d'echo.

echo vs printTest complémentaire pour des chaînes avec quotes simples : echo reste 5 fois plus performante.

echo vs printAutre question évoquée de temps à autre : vaut-il mieux faire plusieurs echo, par exemple pour chaque ligne du code HTML, ce qui est très répandu, ou un seul ? La logique veut qu'une seule instruction soit la manière la plus optimisée de procéder et le test le prouve.

Conclusion : Mieux vaut grouper les chaînes de caractères à afficher et utiliser echo.

Variables

variablesEtrangement, pour initialiser deux variables avec la même valeur, il vaut mieux le faire distinctement plutôt que de profiter de la syntaxe $var1=$var2=$var..=val;.

variablesVaut-il mieux utiliser des noms de variables longs ou courts ? Evidemment le parseur PHP effectue un balayage plus rapide avec des petits noms même si le gain reste faible.

Conclusion : Il ne sert à rien de reprendre en main tous vos scripts pour modifier les noms de variables et leur initialisation.

Conditions

conditions et testsUn switch (manuel) est-il plus indiqué qu'une imbrication de if/elseif/else (manuel) ? Apparemment non même si l'écart est peu significatif.

conditions et testsL'opérateur ternaire (?:) est souvent utilisé, par commodité d'écriture. Il semble plus compact à l'oeil or son exécution ne l'est pas. Un simple couple if/else est plus rapide.

conditions et testsPeu connu, le test === tient compte non seulement des valeurs, mais aussi des types. Il est donc plus rapide car aucune conversion n'est faite. Il me semble néanmoins ambigü car la notion de types en PHP est très faible.

Conclusion : Un bon vieux if reste convenable, et peaufinable avec un test ===.

Tableaux

tableauxL'initialisation basique avec un [ ] est plus performante que la fonction array(). Attention à cette méthode pour les tableaux à plusieurs dimensions il faut le plus souvent combiner les deux.

Conclusion : Ce n'est qu'une petite partie de l'utilisation de tableaux. Les opérations de tri sont autrement plus gourmandes en ressources et tout dépend du déroulement de votre script.

A suivre...