PHP : benchmark des fonctions de base

En PHP, comme dans plusieurs langages de programmation, il existe souvent plusieurs méthodes pour arriver au même résultat. Lors de projets relativement légers, on peut utiliser n’importe quelle méthode, le résultat sera la même, avec aucune différence visible sur les temps d’exécution. En revanche, lors de projets plus complexes, le choix des instructions peut être crucial.

Voici quelques exemples chronométrés de fonctions php, afin de voir ce qu’il convient d’utiliser.

Méthodologie

Le premier point est de choisir des méthodes dont le résultat est exactement le même. Pour cela, nous allons choisir des instructions très simples

Une fois l’instruction choisie, on va enregistrer un timer ( microtime(true) )lancer un nombre important d’itérations sur cette instruction (10 millions de fois), puis enregistrer un nouveau timer. La différence entre les deux timers va indiquer le temps d’exécution de la boucle.

Afin de mesurer un éventuel risque d’erreur, nous répétons cette opération 100 fois, et nous retenons le temps maximum, le temps minimum, ainsi que la moyenne des temps d’exécution.

Afin de ne pas parasiter les traitements, le script php appelé sera le plus simple possible : pas de session, pas d’appel à des includes.
De même, la machine sur laquelle sont lancés ces traitements est un poste de travail, non connecté à Internet au moment des tests, et avec le minimum de programmes en cours d’exécution.

Les temps obtenus seront bien entendu variables en fonction de la puissance et de la disponibilité de la machine de traitement, et ne doivent pas être pris comme une référence pour d’autres applications. L’objectif est uniquement de mesurer les différences de traitements entre deux instructions.

Les chaines de caractères

Voici plusieurs méthodes pour concaténer des chaines de caractères. Au début du script, nous initialisons la variable $test

$test = 'test';

Méthode 1 : variable dans chaîne entre guillemets

for($i=0;$i<10000000;$i++)
{
	$myVar = "concat $test";
}

Les temps obtenus sont :

Mini : 945.5841 ms
Maxi : 1378.978 ms
moyenne : 984.9501 ms

Méthode 2 : une chaîne avec guillemets, puis une variable

for($i=0;$i<10000000;$i++)
{
	$myVar = "concat " . $test;
}

Les temps obtenus sont :

Mini : 737.8411 ms
Maxi : 928.447 ms
moyenne : 774.0768 ms

Méthode 3 : une chaîne entre quotes, puis une variable

for($i=0;$i<10000000;$i++)
{
	$myVar = 'concat ' . $test;
}

Les temps obtenus sont :

Mini : 746.197 ms
Maxi : 1010.2661 ms
moyenne : 794.7649 ms

Conclusion

La différence entre les méthodes 2 et 3 n'est pas flagrante. En revanche, on voit que la méthode 1 est beaucoup plus longue que les autres. Il ne faut pas utiliser des variables dans des chaines entre guillemets.

les instructions conditionnelles

Méthode 1 : switch simple

for($i=0;$i<10000000;$i++)
{
	switch($test)
	{
		case 1:
			$myVar = 'concat ' . $test;
			break;
		default:
			$myVar = 'concat ' . $test;
			break;
	}
}

Les temps obtenus sont :

Mini : 1060.993 ms
Maxi : 1511.966 ms
moyenne : 1120.2844 ms

Méthode 2 : if .. else

for($i=0;$i<10000000;$i++)
{
	if($test == 1)
		$myVar = 'concat ' . $test;
	else
		$myVar = 'concat ' . $test;
}

Les temps obtenus sont :

Mini : 1323.8921 ms
Maxi : 1549.8312 ms
moyenne : 1374.5758 ms

Conclusion

La syntaxe switch est un peu plus efficace que les if ... else. A noter que la différence de temps de traitement est encore plus importante quand on rajoute des conditions.

Conclusion générale

Ce ne sont que deux exemples parmi tant d'autres. On peut déjà trouver sur internet des benchmarks sur les fonctions php, et il est important d'en tenir compte dans vos projets. Attention toutefois aux dates, certains benchs datent un peu et les évolutions de php font que les performances changent vraiment selon les versions.

Si vous voulez faire des tests vous même, voici l'intégralité du code que j'ai utilisé :

$test = 'test';
$compteur = 0;
for($total = 0;$total <= 100; $total++)
{
	$debut = microtime(true);
	for($i=0;$i<10000000;$i++)
	{
		switch($test)
		{
			case 1:
				$myVar = 'concat ' . $test;
				break;
			default:
				$myVar = 'concat ' . $test;
				break;
		}
	}
	$fin = microtime(true);
	$diff = $fin - $debut;
	if(empty($mini))
		$mini = $diff;
	if(empty($maxi))
		$maxi = $diff;
	if($diff < $mini)
		$mini = $diff;
	if($diff > $maxi)
		$maxi = $diff;
	$compteur += $diff;
}
echo "
Mini : " . round($mini*1000,4) . ' ms'; echo "
Maxi : " . round($maxi*1000,4) . ' ms'; $moyenne = ($compteur / $total); echo "
moyenne : " . round($moyenne*1000,4) . ' ms';

2 thoughts on “PHP : benchmark des fonctions de base

  1. Si je ne dis pas de bêtise le « break; » dans la section du default: du switch est en trop. Il crée une instruction de saut qui peut être enlevé. D’ailleurs je me demande si on gagne du temps en l’enlevant ?. Normalement oui.

    1. Excellente remarque, le break final est en trop. Je viens de refaire les tests à l’instant :
      – avec le break final :
      Mini : 1088.1729 ms
      Maxi : 1623.6138 ms
      moyenne : 1166.4585 ms
      – sans le break final :
      Mini : 1090.5011 ms
      Maxi : 1718.8041 ms
      moyenne : 1208.7551 ms

      Donc a priori, aucune différence notable de performances malgré cette erreur.

Répondre à Stéphane DEWITTEAnnuler la réponse.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.