Articles

Ne faites pas d'erreur

  • Ecrit par Damien Seguy
Image pour le titre du contenu
Quand on trouve son application PHP un peu lente, on cherche à optimiser son code : c'est naturel. Outre des conseils couvrants l'usage d'APC (ou d'un autre accélérateur de code), la réduction des inclusions, ou le choix judicieux d'une fonction, il y a un conseil que l'on voit moins souvent : SUPPRIMER LES ERREURS!


Les erreurs sont ces messages qui défigurent les sites Web, et que PHP remonte quand il rencontre une situation étrange : une variable non initialisée, un argument qui manque, etc. Les premiers réflexes, certes sains, sont de supprimer les affichages (dans php.ini, display_errors = 0), et la collecte (dans php.ini, error_reporting = 0). Prenons un petit script pour bien comprendre :
#!/usr/bin/php
<?php
 
$debut = microtime(true);
 
for($i = 0; $i <  100000; $i++) {
  $x = $y + 1;
}
 
$fin = microtime(true);
print "Duree : ".number_format(1000 * ($fin - $debut), 2)." ms\n";
?
Ce script produit dix mille erreurs inoffensives ($y n'existe pas, mais est utilisé). Avec error_reporting = E_ALL, on obtiens le résultat en 3 à 5 secondes.
Notice: Undefined variable: y in /Users/macbook/Desktop/test.php on line 10
 
 
 
Notice: Undefined variable: y in /Users/macbook/Desktop/test.php on line 10
 
 
 
Notice: Undefined variable: y in /Users/macbook/Desktop/test.php on line 10
 
Duree : 5,162.76 ms
 
L'essentiel du temps est en fait perdu dans l'affichage de ces erreurs. Première option, supprimer les affichages avec display_error. Résultat :
Duree : 136.18 ms
 
Ouf... On est passé de 5000 ms à 136 ms. Le pourcentage d'augmentation est incroyable, mais dû au système. On peut aussi compter 0,04864 ms pour une erreur : 5 centième de secondes pour une erreur. Et si on ignore les erreurs ? (error_reporting = 0);
Duree : 117.79 ms
 
Oui, on grappille encore quelques fractions de secondes (env. 20%), sans que cela soit formidable. Que se passe-t-il ici? En fait, quand on demande à PHP de ne plus rapporter d'erreurs, il continue de les traquer, mais les ignore. Mais cela lui fait quand même du travail supplémentaire, car il doit perdre du temps à ignorer ces erreurs. En fait, il n'y a pas de moyen pour débrayer le suivi interne des erreurs de PHP, ce qui fait qu'un script qui n'est pas compatible avec E_STRICT est nettement plus lent qu'un script qui ne produit aucune erreur. Et si on supprime les erreurs? Ici, cela signifie qu'on corrige le code en initialisant $y. Et on obtient encore 80% d'augmentation :
Duree : 19.51 ms
 
Au final, la génération d'erreur dans le code PHP conduit inévitablement à des pertes de performances. Et, par expérience, ces mêmes erreurs sont à la source de problèmes de sécurité et de bogues. Vous avez donc tout intérêt à travailler en suivant les bonnes pratiques :
  • Développez avec un rapport d'erreur de E_STRICT et supprimez les erreurs que PHP affiche au fur et à mesure du codage
  • En production, utilisez display_errors = 0
  • Gardez error_reporting=E_STRICT, ou bien aussi haut que possible : même masquée, une erreur vous coûte en performances

Vous devez vous connecter pour commenter