Bonsoir,
Dans mes site Internet je me mets à utiliser beaucoup de classes liées au fonctionnement du système (le moteur site) et non pas au métier (les données du site).
Notamment pour une connexion avec la base de données, mais également pour logger les événements, pour charger des classes (contenue dans des fichiers spécifiques) ou des objets linéarisés (serialized).
Jusqu’à présent, pour ce genre de classes Manager/Service, je faisais des classes statiques afin qu’elle soient accessible facilement depuis n’importe quel pan de code, puis j’ai découvert les singletons qui sont aussi facilement accessible mais, au contraire d’une classe statique, peuvent être étendue (héritage).
Je me suis demandé ce qui de la classe statique (ne contenant que des attributs et méthodes static) ou du Singleton était le plus rapide à l’utilisation.
J’ai donc fait le script suivant :
<?php
class Timer {
private $start_mtimestamp = NULL;
private $stop_mtimestamp = NULL;
public function __construct() {}
public function start() { $this->start_mtimestamp = microtime(true); }
public function stop() { $this->stop_mtimestamp = microtime(true); }
public function getDuration() {
if($this->start_mtimestamp == NULL) { // Si le compteur n'a même pas été lancé
return -1;
}
else {
if($this->stop_mtimestamp == NULL) { // Si le compteur est en cours
$this->stop(); // On le stoppe
}
return strtr(sprintf('%0.3f', ($this->stop_mtimestamp - $this->start_mtimestamp)), '.', ',');
}
}
};
class ClasseNormale {
private $var1;
private $var2;
public function __construct() {}
public function setVar1($var1) { $this->var1 = $var1; }
public function setVar2($var2) { $this->var2 = $var2; }
public function getVar1() { return $this->var1; }
public function getVar2() { return $this->var2; }
};
class ClasseSingletonne {
private static $instance = NULL;
private $var1;
private $var2;
public function __construct() {}
public static function _getInstance() {
if(self::$instance == NULL) {
self::$instance = new ClasseSingletonne();
}
return self::$instance;
}
public function setVar1($var1) { $this->var1 = $var1; }
public function setVar2($var2) { $this->var2 = $var2; }
public function getVar1() { return $this->var1; }
public function getVar2() { return $this->var2; }
};
class ClasseStatique {
private static $var1;
private static $var2;
public static function setVar1($var1) { self::$var1 = $var1; }
public static function setVar2($var2) { self::$var2 = $var2; }
public static function getVar1() { return self::$var1; }
public static function getVar2() { return self::$var2; }
};
$timerClasseNormale = new Timer();
$timerClasseNormale->start();
for($i = 0; $i <= 10000; $i++) {
$classeNormale = new ClasseNormale();
$classeNormale->setVar1('A');
$classeNormale->setVar2('Z');
$classeNormale->setVar1($classeNormale->getVar1() . $classeNormale->getVar2());
$classeNormale->setVar2(':)');
}
$timerClasseNormale->stop();
$timerClasseSingletonne = new Timer();
$timerClasseSingletonne->start();
for($i = 0; $i <= 10000; $i++) {
ClasseSingletonne::_getInstance()->setVar1('A');
ClasseSingletonne::_getInstance()->setVar2('Z');
ClasseSingletonne::_getInstance()->setVar1(ClasseSingletonne::_getInstance()->getVar1() . ClasseSingletonne::_getInstance()->getVar2());
ClasseSingletonne::_getInstance()->setVar2(':)');
}
$timerClasseSingletonne->stop();
$timerClasseStatique = new Timer();
$timerClasseStatique->start();
for($i = 0; $i <= 10000; $i++) {
ClasseStatique::setVar1('A');
ClasseStatique::setVar2('Z');
ClasseStatique::setVar1(ClasseStatique::getVar1() . ClasseStatique::getVar2());
ClasseStatique::setVar2(':)');
}
$timerClasseStatique->stop();
echo '<h2>ClasseNormale</h2>' . "\n";
echo 'Var1 : ' . $classeNormale->getVar1() . '<br />' . "\n";
echo 'Var2 : ' . $classeNormale->getVar2() . '<br />' . "\n";
echo 'Timer : ' . $timerClasseNormale->getDuration() . '<br />' . "\n";
echo '<h2>ClasseSingletonne</h2>' . "\n";
echo 'Var1 : ' . ClasseSingletonne::_getInstance()->getVar1() . '<br />' . "\n";
echo 'Var2 : ' . ClasseSingletonne::_getInstance()->getVar2() . '<br />' . "\n";
echo 'Timer : ' . $timerClasseSingletonne->getDuration() . '<br />' . "\n";
echo '<h2>ClasseStatique</h2>' . "\n";
echo 'Var1 : ' . ClasseStatique::getVar1() . '<br />' . "\n";
echo 'Var2 : ' . ClasseStatique::getVar2() . '<br />' . "\n";
echo 'Timer : ' . $timerClasseStatique->getDuration() . '<br />' . "\n";
?>
Ce qui me donne les résultats suivants :[quote=""]
ClasseNormale
Var1 : AZ
Var2 :
Timer : 0,160
ClasseSingletonne
Var1 : AZ
Var2 :
Timer : 0,723
ClasseStatique
Var1 : AZ
Var2 :
Timer : 0,215
[/quote]
Il semble donc qu’une classe statique est plus rapide qu’un singleton.
On remarque également que la classe normale (ni statique, ni singleton) est encore plus rapide : cependant, pour ce servir d’un Manager/Service implémenté avec une classe normale il faut, à tout moment, avoir un pointeur vers l’instance de cette classe, ce qui obligerait à faire un global (dans fonctions et méthodes) dont j’ignore le coût processeur.
Qu’en pensez-vous ?