Php5 - classe de benchmark

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 646 fois - Téléchargée 31 fois


Contenu du snippet

Bon bah voila, plutôt que devoir se taper 40 fois l'écriture de "microtime(true)", de devoir se taper 40 fois les opérations à écrire $stop-$start... je me suis dit : Autant que j'automatise ça et au plus vite !

Alors j'ai fait une petite classe... non en faite j'en ai fait deux. Pourquoi 2 ? La première classe (mark) sert à instancier chaque benchmark en une classe. La seconde classe (bench) permet d'interfacer la classe mark avec le programmeur.
Pourquoi avoir fait ca ? Parce que je trouve que c'est plus jolie à faire et que ca rend le coté orienté objet un peu plus concret comme ca.

Ma classe gère le multi-benching au passage, donc vous pouvez lancer 40 benchs en même temps, ca marchera très bien :)
Mais voyons le code en détail :

Source / Exemple :


<?php
<?php
class bench {
 
 protected $bench = array(); // Contient tous les marqueurs de bench
  
 public function __construct($name) {
  $this->init($name); // Initialisation du premier marqueur (obligatoire) à l'instanciation de classe.
 }
 
 public function init($name) {
  $this->bench[$name] = new mark;
 }
 
 public function __get($name) { // Méthode magique (j'expliquerai plus loin)
  
   if ( isset($this->bench[$name]) ) {
        return $this->bench[$name];
   } else {
        throw new Exception ($name.' n\'existe pas en tant que marque de bench !');
   }
  
  }

}

class mark {

 protected $start; // Début du compteur
 protected $stop; // Fin de compteur
 protected $time; // Résultat du bench

 final public function start() {
  $this->start = microtime(true);
 }
 
 final public function stop() {
  $this->stop = microtime(true);
 }
 
 final public function getResult() {
  $this->time = $this->stop - $this->start;
  return $this->time;
 }
 
}
?>
<?php
/* Bon jusque la, la lecture est vraiment très simple. Il n'y a que pour le __get que je vais vous expliquer (pour ceux qui ne le savent pas !). */
// J'instancie ma classe bench en premier, avec comme argument le nom du bench que je vais réaliser.
$bench = new bench('page');

// Ici, je vais bencher toute ma page !
// Je commence donc maintenant :
$bench->page->start();

/* Et oui, le 'page' que j'ai passé en argument est devenu un objet ! Cela est réalisable grâce à la méthode magique __get. En effet, si on regarde bien le code, je n'ai pas déclaré de paramètre $page à ma classe... mais seulement $bench qui est un tableau ! Grâce à _get() je vais faire la relation entre le tableau $bench qui est comme ca : $bench = array( 'page' => object(mark) ) et le paramètre $page qui lui n'existe pas ! */

// On continu donc l'éxécution de la page :
<p></p>
<a></a>

// hop, fin de page, j'arrète le chrono :
$bench->page->stop();

// Je récupère pour pouvoir visualiser le temps d'éxécution :
echo $bench->page->getResult();

// Et voila comment on bench une page facilement ! Maintenant plus compliquer, je vais faire trois bench... deux pour des requètes SQL, une pour ma page entière !

$bench = new bench('page');
$bench->init('sql1');
$bench->init('sql2');

$bench->page->start();

$sql = "SELECT .....";
$bench->sql1->start();
$query = mysql_query($sql);
$bench->sql1->stop();

echo mysql_num_rows($query);

$sql = "SELECT .....";
$bench->sql2->start();
$query = mysql_query($sql);
$bench->sql2->stop();

// suite du code 

// On arrive à la fin :
$bench->page->stop();
// On affiche le tout :
echo 'Bench :<br /><br />';
echo 'Query 1 : '.$bench->sql1->getResult().' <br />';
echo 'Query 2 : '.$bench->sql2->getResult().' <br />';
echo 'Page : '.$bench->page->getResult().' <br />';
?>

Conclusion :


Bon, c'est tout simple... mais au moins, ca aide au niveau d'un benchmark rapide et efficace.
Je n'ai fait aucune gestion d'erreur, ca viendra un peu plus tard :)

C'est parce que Coucou747 m'a demandé une gestion de bench sur mon ancienne classe que je me suis dit de developper quelque chose comme ca.

Si y'a des trucs à modifier, astuces où autres améliorations, je suis toujours preneur !

Merci :)
Ps : Je met en Initié car j'utilise le principe de la méthode magique __get()... autrement c'est tout simple !

A voir également

Ajouter un commentaire Commentaires
Messages postés
1
Date d'inscription
mercredi 17 janvier 2007
Statut
Membre
Dernière intervention
11 avril 2012

Juste comme ça, je me suis permis de rajouter une méthode à ta class bench().

Plutôt que de passer par des echo $bench->variable->getResult(); pour chaque variable, je fais comme ça.

public function allResult() {
foreach ($this->bench as $key => $value) {
$array[$key] = $value->getResult();
}
return Fonction::printr($array);
}

Fonction::printr() n'est qu'un print_r() entouré de balise

Moins esthétique que du echo mais plus rapide à mettre en oeuvre pour du debug ;)

Merci beaucoup pour cette class en tout cas.
Messages postés
1
Date d'inscription
vendredi 11 décembre 2009
Statut
Membre
Dernière intervention
21 février 2010

Merci groupe codes sources
Messages postés
1293
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015

Sympa je ne connaissais pas la fonction magique __get()... je suis pas encore trop php5 les serveurs pour lesquels je code étant encore en php4... .. .

j'ais une class que j'avais fais et qui utilise un principe d'auto increment pour gérer automatiquement plusieurs benchmarks imbriqués sans avoir à créer un nom à chaque fois... .. .

en gros tu as un attribut $benchmarkid qui s'increment de 1 lorsqu'un bench est lancé quand tu lance le benchmark tu fais

$benchId = $monObjet->startBench('la description');

ça lance le timer et renvoi l'id du benchmark et quand tu veux stoper le bench et/ou récupérer le résultat tu fais

$monObjet->stotBench($benchId); pour juste le stoper ou $monObjet->getBench($benchId); pour le stopper, s'il ne l'est pas déja, et pour récupérer le résultat

les infos sont stocké dans un tableau comme suit...

array(
'desc' => 'le nom de la fonction testée',
'start' => 'le timer de départ',
'stop' => 'le timer de fin',
'total' => 'le résultat du benchmark',
'isFinish' => 'pour savoir si le bench est finit ou non pour le get'
),

L'avantage... t'as pas a faire de nom perso pour chaque bench vu que c'est un id numérique qui est attribué ça permet d'imbriquer des benchmark les uns dans les autres quand tu test par exemple une méthode d'une class qui fait elle même appel à d'autre méthodes... le désavantage... j'en vois pas si ce n'est peut être que les résultats sont stockés dans un taébleau un peu plus bordellique... et encore que... .. .

Voili voilou... rien de mirobolant... de toute façon pour une class de benchmark... lol... c'est juste une autre façon de faire... .. .

@ tchaOo°
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
4
Ok ok, je vais changer...

Il ne me reste plus qu'à faire une interface avec zone de texte pour pouvoir faire ca plus rapidement que de devoir taper du code à chaque fois.

Jvais concocter ca dans pas longtemps (maintenant que j'ai optimisé ma classe de DB, je vais pouvoir le faire !)
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
25
Ouais je me suis aussi demandé pourquoi protected et pas private, en fait. Shingara a raison.
Afficher les 12 commentaires

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.