Class bench - comparateur de code php avec différence entre chaque code et code plus rapide

Contenu du snippet

Voila une petite classe permettant de régler définitivement les litiges pour les syntaxes en PHP.

Appelée comme suit :

$bench = new bench();

$bench->benching(array('for($i=1; $i<10000; $i++) {$a = file_exists(\'class.php\'); }', 'for($i=1; $i<10000; $i++) {$a = is_file(\'class.php\'); }'), array('10000 itérations avec file_exists(1er bench)', 'et is_file(2ème bench)'), 10000);

echo $bench->resultat(0);
echo $bench->resultat(1);

echo $bench->compare_bench(0, 1);

echo $bench->resultat(0); // Numéro du bench, le premier est toujours 0 et ainsi de suite ....
echo $bench->resultat(1);

echo $bench->compare_bench(0, 1);

benching() prend comme argument benching($code_a_traiter, $nom_du_bench, $nombre_de_boucles, $nb_decimales, $show_result)

$code et $nom_du_bench doivent être obligatoirement des tableaux ;)

le nom du bench est par défaut égal à undefined si vous ne lui donnez pas de noms, en cas de plusieurs comparatifs de benchs, il est préférable
de mettre un nom clair qui s'affichera à côté du bench. Exemple : 10 000 itérations de echo '$variable';

$nb_iterations représente le nombre de fois que vous allez boucler le code (il est préférable d'en faire 10 000 au moins pour évaluer deux codes)
Il sera utilisé pour calculer le nombre de microsecodes nécessaires pour exécuter le code à chaque fois, ne vous trompez pas, sinon vous fausserez les calculs

En laissant la variable $show_result à TRUE, vous afficherez ce qu'envoie le code passé à eval. Il est conseillé de laisser la variable à TRUE si vous n'avez pas d'echo dans votre code. Si vous voulez par exemple cacher 10000 echo, il est conseillé pour des raisons d'affichage de mettre la variable à FALSE. Il est uniquement conseillé de laisser TRUE pour voir les erreurs que produit eval en cas d'erreur de syntaxe de $code car eval n'arrête pas le script en cas de mauvaise syntaxe, ob_end_clean ne vous affichera pas l'erreur de syntaxe si $show_result est à FALSE.

Notez que dès fois, les résultats varient, alors ne rafraichissez pas trop vite la page, sinon ca passe en négatif certaines fois. Et comptez le code le plus rapide après plusieurs résultats en faveur de celui-ci, ne vous fiez pas à un seul résultat. N'hésitez pas à poster vos résultats ;)

Source / Exemple :


<?php
class bench {

	function benching($code = '', $nom_du_bench = 'undefined', $nb_iterations = 10000, $show_result = TRUE) {
			// On commence par mettre un set_time_limit à 0 au cas où ...
		if(intval(ini_get('safe_mode')) == 0) {
			set_time_limit(0);
				}
		
		// Si $code n'est pas un tableau, on le transforme en tableau ^_^
		if(!is_array($code)) {
		die ('La variable $code n\'est pas un tableau ! ');
		}
		
		if(!is_array($nom_du_bench)) {
		die ('La variable $nom_du_bench n\'est pas un tableau ! ');
		}

		 //print_r($nom_du_bench);
		// On boucle pour chaque élément de $code
		foreach($code as $key => $value){
	
		if(!isset($this->bench_number)) {
		// On initialise le compteur de benchs à 0 si on est entrain de faire le premier bench
		$this->bench_number = 0;
				}
		if($code != '') {
			// On enregistre les variables passées en arguments dans la fonction dans un tableau qui correspondra à chaque bench
			$this->bench_info[$this->bench_number]['nom'] = $nom_du_bench[$this->bench_number];
			$this->bench_info[$this->bench_number]['numero'] = $this->bench_number;
			$this->bench_info[$this->bench_number]['iterations'] = $nb_iterations;
		
			$tableau=array('<?php'=>'','<?'=>'','?>'=>'');
			$this->code=strtr($code,$tableau);

			// Lancement du compteur //
			$this->start[$this->bench_number]=microtime();
			// On créé un fichier temporaire où sera contenu le code
			$tempfn = md5(time()).'.php';
			$handle = fopen ($tempfn, 'w+');
			fwrite($handle, '<?php '.$code[$key].' ?>');
			fclose($handle);
			
			if(!$show_result) {ob_start();} // Si $show_result est à FALSE, on met tout ce qui est envoyé au navigateur en cache.
			include($tempfn);
			if(!$show_result) {ob_end_clean();} // Et on supprime le tout. Rien n'est alors envoyé au navigateur.
			
			unlink($tempfn);
			// Fin du compteur
			$this->end[$this->bench_number]=microtime();

			// On fait la différence entre les deux microtimes.
			$this->bench_info[$this->bench_number]['duree']= $this->end[$this->bench_number] - $this->start[$this->bench_number];
			// On enregistre le nombre d'itérations et le code pour le bench
			$this->bench_info[$this->bench_number]['instructions'] = round($nb_iterations / $this->bench_info[$this->bench_number]['duree']);
			$this->bench_info[$this->bench_number]['code'] = $code[$key];
			
			// On incrémente le compteur bench_number
			$this->bench_number++;
			
			}
		}

	}

			// Cette fonction sert à afficher le résultat d'un bench, en affichant chaque variable enregistré dans le tableau correpondant au bench numéro $bench_number
	function resultat($bench_number = 0) {
	
			// On vérifie que le bench $bench_number existe bien
			if($this->bench_info[$bench_number]['code'] == '') {
			// On retourne une erreur en cas d'inexistance //
			return 'Bench '.$bench_number.' inexistant, résultat impossible à afficher';
					}
			// Ou on affiche les résultats si le bench existe bel et bien
			return '<br /><b>Bench N°' .$bench_number. '</b> ------- <i>' .$this->bench_info[$bench_number]['nom']. '</i><br /> Code : <b>'.htmlentities($this->bench_info[$bench_number]['code']). '</b> <br />Durée : ' .$this->bench_info[$bench_number]['duree'].'  secondes<br />Vitesse : ' .number_format($this->bench_info[$bench_number]['instructions'],0, ',', ' '). ' instructions par secondes<br /><br />';
			
		}

			// Cette fonction sert à comparer deux benchs (savoir lequel est le plus rapide, de combien, etc...) en donnant les deux numéros de benchs correspondants
			function compare_bench($bench_number1 = '0', $bench_number2 = '1') {
			
			// On vérifie que les benchs $bench_number1 et $bench_number2 existent bien
			if($this->bench_info[$bench_number1]['code'] == '' || $this->bench_info[$bench_number2]['code'] == '') {
			// On retourne une erreur en cas d'inexistance de l'un ou de l'autre
			return 'Bench '.$bench_number1.' ou '.$bench_number2.' inexistant';
					}
			elseif($this->bench_info[$bench_number1]['duree'] > $this->bench_info[$bench_number2]['duree']) {
			// Ceci affiche la différence entre les deux scripts en microsecondes, il suffit d'enlever le 1 000 000 de $this->diff pour avoir le résultat en secondes.
			$this->diff = round(($this->bench_info[$bench_number1]['duree'] - $this->bench_info[$bench_number2]['duree'])*1000000, 3);
			return '<br />Le bench N°' .$this->bench_info[$bench_number2]['numero']. ' gagne avec ' .$this->diff. ' microsecondes de moins en temps d\'exécution<br />Soit environ ' .round($this->bench_info[$bench_number1]['duree'] / $this->bench_info[$bench_number2]['duree'], 2). ' fois plus rapide que le bench N°' .$this->bench_info[$bench_number1]['numero']. '<br /><b>En conclusion : </b><br /><br /><b>' .htmlentities($this->bench_info[$bench_number2]['code']). '</b><br />est plus rapide que <br /><b>' .htmlentities($this->bench_info[$bench_number1]['code']).'</b>';
					}
			elseif($this->bench_info[$bench_number2]['duree'] > $this->bench_info[$bench_number1]['duree']) {
			// Ceci affiche la différence entre les deux scripts en microsecondes, il suffit d'enlever le 1 000 000 de $this->diff pour avoir le résultat en secondes.
			$this->diff = round(($this->bench_info[$bench_number2]['duree'] - $this->bench_info[$bench_number1]['duree'])*1000000, 3);
			return '<br />Le bench N°' .$this->bench_info[$bench_number1]['numero']. ' gagne avec ' .$this->diff. ' microsecondes de moins en temps d\'exécution<br />Soit environ ' .round($this->bench_info[$bench_number2]['duree'] / $this->bench_info[$bench_number1]['duree'], 2). ' fois plus rapide que le bench N°' .$this->bench_info[$bench_number2]['numero']. '<br /><b>En conclusion : </b><br /><br /><b>' .htmlentities($this->bench_info[$bench_number1]['code']). ' </b><br />est plus rapide que <br /><b>' .htmlentities($this->bench_info[$bench_number2]['code']).'</b>';
					}

			elseif($this->bench_info[$bench_number2]['duree'] == $this->bench_info[$bench_number1]['duree']) {
			// Bien que cela ne soit fort peu possible, on envisage que les deux benchs aient le même temps d'exécution
			return 'Il n\'y a presque aucune différence entre ces deux codes.';
					}
		}

}
?>

Conclusion :


Quelques benchs (je rajouterais au fur et à mesure si quelques personnes font des tests concluants ;) )

is_file est environ 1,20 à 1,80 fois plus rapide que file_exists quand le fichier existe.

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.