Bonjour à vous,
suite à un débat initié dans le burreau au sein du quel je travail, j'ai décider d'ouvrir le débat ici, et histoire d'etre constructif, j'ai effectué qulques tests.
Si on s'en tien a la documentation : http://php.net/manual/fr/function.mt-rand.php
mt_rand() est meilleure car plus aléatoire et 4x plus rapide (ce qui est non négligeable).
Malheureusement... il semblerait qu'on nous ait menti! Où du moins, a moitié, mt_rand() semble plus lent que rand() mais a un taux d'erreur moins élevé, donc génére mieux l'aléatoire.
C'est la conclusion que j'en ai tirer après avoir répété le test plusieurs fois (effectuer sur 1 million de boucle chacun):
Donc plus long, mais plus aléatoire, après faut faire sont choix.
Cependant on peut améliorer (quelque soit la fonction utilisé) la valeur de l'aléatorie en baissant le taux d'erreurs via les fonction srand() et mt_srand() qui initialise le générateur d'aléatoire.
Voilà ce que ça donne avec les générateurs pour les deux fonctions:
On note donc une légère amélioration des résultats grâce à l'initialisation.
Certains se posent sans doute la question, donc je vais y répondre, qu'es ce que j'entends par "taux d'erreur"?
En fait c'est l'écart par rapport à l'équiprobabilité théorique que l'on doit trouver.
Qu'es ce que ça veux dire? Ça veux dire que dans l'absolue, un générateur d'aléatoire, parfait est censé répartir équitablement entre toute les solutions possible (c'est l'équiprobabilité: une probabilité égal entre chaque solution possible).
Autrement dit sur un jet de dé à 6 faces et sur un très grand nombre de lancé, il est censé être sortie le même nombre de fois chaque chiffre de 1 à 6.
Donc pour en revenir a notre fonction, si elle fait X boucle, et un tirage entre 1 et 100 par exemple, on est censé trouvé X/100 tirage pour chaque chiffre entre 1 et 100. Les erreurs sont donc toutes les variations par rapport à ce chiffre théorique.
Autrement dit, pour reprendre l'exemple d'un lancé de dé, si j'obtiens:
98 tirage du 1, 102 du 2, 100 du 3, 99 du 4, 101 du 5 et 100 du 6,
alors si on additionne tout ce qui dépasse la valeur théorique (100 ici), on obtient 6 erreurs.
Pour ce qui veulent, voilà le code que j'utilise pour le test, vous pouvez testé chez vous et me dire si vous en tirez les même conclusion:
Voilà, qu'en pensez vous?
De base j'utilise mt_rand() et sans initialisé le générateur (je ne connaissais pas trop ce procédé)
Qu'utilisez vous?
suite à un débat initié dans le burreau au sein du quel je travail, j'ai décider d'ouvrir le débat ici, et histoire d'etre constructif, j'ai effectué qulques tests.
Si on s'en tien a la documentation : http://php.net/manual/fr/function.mt-rand.php
mt_rand() est meilleure car plus aléatoire et 4x plus rapide (ce qui est non négligeable).
Malheureusement... il semblerait qu'on nous ait menti! Où du moins, a moitié, mt_rand() semble plus lent que rand() mais a un taux d'erreur moins élevé, donc génére mieux l'aléatoire.
C'est la conclusion que j'en ai tirer après avoir répété le test plusieurs fois (effectuer sur 1 million de boucle chacun):
Citation :rand(1, 100) à mis 6.7577540874481 secondes à s'executer pour 1000000 boucles.
Taux Erreur : 0.001417 - 0.1417% (1417)
mt_rand(1, 100) à mis 6.9153845310211 secondes à s'executer pour 1000000 boucles.
Taux Erreur : 0.008029 - 0.8029% (8029)
rand(1, 10000) à mis 6.8464136123657 secondes à s'executer pour 1000000 boucles.
Taux Erreur : 0.122217 - 12.2217% (122217)
mt_rand(1, 10000) à mis 7.1655714511871 secondes à s'executer pour 1000000 boucles.
Taux Erreur : 0.080141 - 8.0141% (80141)
Donc plus long, mais plus aléatoire, après faut faire sont choix.
Cependant on peut améliorer (quelque soit la fonction utilisé) la valeur de l'aléatorie en baissant le taux d'erreurs via les fonction srand() et mt_srand() qui initialise le générateur d'aléatoire.
Voilà ce que ça donne avec les générateurs pour les deux fonctions:
Citation :Générateur initialisé
rand(1, 100) à mis 6.8553650379181 secondes à s'executer pour 1000000 boucles.
Taux Erreur : 0.001395 - 0.1395% (1395)
mt_rand(1, 100) à mis 7.0287108421326 secondes à s'executer pour 1000000 boucles.
Taux Erreur : 0.008363 - 0.8363% (8363)
rand(1, 10000) à mis 6.9092042446136 secondes à s'executer pour 1000000 boucles.
Taux Erreur : 0.122185 - 12.2185% (122185)
mt_rand(1, 10000) à mis 7.2302443981171 secondes à s'executer pour 1000000 boucles.
Taux Erreur : 0.078943 - 7.8943% (78943)
On note donc une légère amélioration des résultats grâce à l'initialisation.
Certains se posent sans doute la question, donc je vais y répondre, qu'es ce que j'entends par "taux d'erreur"?
En fait c'est l'écart par rapport à l'équiprobabilité théorique que l'on doit trouver.
Qu'es ce que ça veux dire? Ça veux dire que dans l'absolue, un générateur d'aléatoire, parfait est censé répartir équitablement entre toute les solutions possible (c'est l'équiprobabilité: une probabilité égal entre chaque solution possible).
Autrement dit sur un jet de dé à 6 faces et sur un très grand nombre de lancé, il est censé être sortie le même nombre de fois chaque chiffre de 1 à 6.
Donc pour en revenir a notre fonction, si elle fait X boucle, et un tirage entre 1 et 100 par exemple, on est censé trouvé X/100 tirage pour chaque chiffre entre 1 et 100. Les erreurs sont donc toutes les variations par rapport à ce chiffre théorique.
Autrement dit, pour reprendre l'exemple d'un lancé de dé, si j'obtiens:
98 tirage du 1, 102 du 2, 100 du 3, 99 du 4, 101 du 5 et 100 du 6,
alors si on additionne tout ce qui dépasse la valeur théorique (100 ici), on obtient 6 erreurs.
Pour ce qui veulent, voilà le code que j'utilise pour le test, vous pouvez testé chez vous et me dire si vous en tirez les même conclusion:
<?php
############################################# INITIALISATION #####################################################
set_time_limit(0);
$NB_BOUCLE = 1000000;
$INI=true;
if($INI)
{
echo 'Générateur initialisé<br/><br/>';
mt_srand(round(microtime(true)));
srand(round(microtime(true)));
}
############################################# PROGRAMME PRINCIPAL #####################################################
executeTest('rand', 100, $NB_BOUCLE);
executeTest('mt_rand', 100, $NB_BOUCLE);
executeTest('rand', 10000, $NB_BOUCLE);
executeTest('mt_rand', 10000, $NB_BOUCLE);
############################################# FONCTIONS #####################################################
//remplit le compteur $tab avec les resultat des random
//@return : temps d'exec du random
function doRandom(&$tab, $func, $max, $NB_BOUCLE)
{
$time_total=0;
for ($i = 1; $i < $NB_BOUCLE; ++$i)
{
$time = microtime(true);
$tab[$func(1, $max)]++;
$time_total += microtime(true) - $time;
}
return $time_total;
}
//execute x fois le test de la fonction random passé en parametre (mt_rand ou rand)
//Affiche le temps d'exec et le taux d'erreur
function executeTest($func, $max, $NB_BOUCLE)
{
$tab=array();
$temps_exec = doRandom($tab, $func, $max, $NB_BOUCLE);
$erreur=0;
foreach($tab as $rand => $nb) $erreur += abs($nb - ($NB_BOUCLE/$max));
echo $func.'(1, '.$max.') à mis '.$temps_exec.' secondes à s\'executer pour '.$NB_BOUCLE.' boucles.<br />Taux Erreur : '.($erreur/$NB_BOUCLE).' - '.($erreur*100/$NB_BOUCLE).'% ('.$erreur.')<br/><br/>';
}
?>
Voilà, qu'en pensez vous?
De base j'utilise mt_rand() et sans initialisé le générateur (je ne connaissais pas trop ce procédé)
Qu'utilisez vous?
Dévotion, jeu multijoueur gratuit par navigateur de stratégie et de conquête
The Magic Institute, le jeu de magie médieval fantastique gratuit en ligne
Rapture Studio : créateur de divertissement pour tous
JePolitique.fr - débattons ensemble
JécrisLaConstitution.fr - ne laissons pas les Hommes aux pouvoirs écrire les règles du pouvoir
Je Deviens Citoyen (Association à but non lucratif)
The Magic Institute, le jeu de magie médieval fantastique gratuit en ligne
Rapture Studio : créateur de divertissement pour tous
JePolitique.fr - débattons ensemble
JécrisLaConstitution.fr - ne laissons pas les Hommes aux pouvoirs écrire les règles du pouvoir
Je Deviens Citoyen (Association à but non lucratif)