Différence entre mt rand () Et rand()

Quelle est la différence entre utiliser mt_rand($min, $max) et rand($min, $max) à propos de la vitesse?

25
demandé sur Thomas Rbt 2015-02-27 11:37:52

6 réponses

mise à Jour

depuis PHP 7.1 mt_rand remplace rand complètement, et rand est devenu un alias pour mt_rand. La réponse ci-dessous se concentre sur les différences entre les deux fonctions pour les versions plus anciennes, et les raisons pour introduire mt_rand.


Vitesse n'était pas pourquoi mt_rand a été introduit!

rand la fonction existait bien avant mt_rand, mais il était profondément imparfait. Un PRNG doit obtenir une entropie, un nombre à partir duquel il génère une séquence de nombres aléatoires. Si vous imprimez une liste de dix numéros générés par rand() comme ceci:

for ($i=0;$i<10;++$i)
    echo rand(), PHP_EOL;

La sortie peut être utilisée pour déterminer l' rand seed était, et avec elle, vous pouvez prédire les nombres aléatoires suivants. Il y a des outils là-bas qui font cela, alors google un peu et le tester.

Il y a aussi un problème avec rand relativement rapidement montrant des modèles dans ses nombres aléatoires comme démontré ici. Un problème mt_rand semble résoudre beaucoup mieux, aussi.

mt_rand utilise un meilleur algorithme de randomisation (Mersenne Twist), qui nécessite plus de nombres aléatoires à connaître avant que la graine puisse être déterminée et est plus rapide. Cela ne signifie pas que mt_rand est, par définition, plus rapide que rand, cela signifie seulement que la façon dont les nombres sont générés est plus rapide, et semble n'avoir aucun impact réel sur la performance de la fonction, comme d'autres réponses ici ont démontré.

De toute façon, jetez un coup d'oeil à mt_srand et srand docs. Je suis sûr qu'ils contiendront plus d'informations

Si mt_rand'algorithme se traduit par une augmentation de la performance, alors que c'est bon pour vous, mais c'est une heureuse coïncidence. TL;TR:

mt_rand a été introduit pour résoudre les problèmes qui existent dans rand!

40
répondu Elias Van Ootegem 2017-01-09 13:57:25

mise à Jour (PHP 7.1):

rand() et srand() sont maintenant des pseudonymes de mt_rand() et mt_srand(), respectivement. cela signifie que la sortie pour les fonctions suivantes a des modifications:rand(),shuffle(),str_shuffle() et array_rand().

cela signifie que depuis la version 7.1 il n'y a aucune différence pratique entre les deux parce que rand appelle mt_rand en interne.


Avant PHP 7.1:

en utilisant rand() n'est pas une mauvaise idée si c'est pas utilisé pour des raisons de sécurité, je suis généralement à l'aide de rand() (habitude?).

Si vous avez besoin d'une énorme quantité de nombres aléatoires, vous aurez besoin mt_rand au lieu de rand. mt_rand a une période de 219937 - 1, beaucoup mieux que rand paragraphe 2 32). Jetez un oeil à cet article à propos du motif graphique génération utilisant rand et mt_rand.

Périodicité et entropie sont les seules raisons d'utiliser mt_rand() au lieu de rand() et pas d'amélioration de la sécurité ou de la vitesse.

Mathématiquement mt_rand plus entropie et un plus grand périodicitérand paragraphe 219937 -1 vs. 2 32).

si vous avez besoin de quelques nombres aléatoires et la sécurité est pas un problème, rand fera le travail (obtenir un nombre aléatoire pour décider de lancer un processus de nettoyage).


Tester les améliorations de la vitesse

dans la pratique, il n'y a pas beaucoup de différence de vitesse entre les deux fonctions (peut-être parce que PHP se charge de l'emballage?).

code de test PHP:

<?php
for ($c = 0; $c < 3; $c++) {
  $start = microtime(true);
  $sum = 0.0;
  for ($i = 0; $i < 100000000; $i++) {
    $sum += rand();
  }
  printf('[rand %d] Time: %.3f s%s', $c, microtime(true) - $start, PHP_EOL);
}
for ($c = 0; $c < 3; $c++) {
  $start = microtime(true);
  $sum = 0.0;
  for ($i = 0; $i < 100000000; $i++) {
    $sum += mt_rand();
  }
  printf('[mt_rand %d] Time: %.3f s%s', $c, microtime(true) - $start, PHP_EOL);
}

Tests en PHP 7.0.19:

$ php timing.php
[rand 0] Time: 4.658 s
[rand 1] Time: 4.664 s
[rand 2] Time: 4.654 s
[mt_rand 0] Time: 4.267 s
[mt_rand 1] Time: 4.255 s
[mt_rand 2] Time: 4.261 s

Tests en PHP 5.4.45 (plus lent de la machine):

$ php timing.php
[rand 0] Time: 10.862 s
[rand 1] Time: 10.889 s
[rand 2] Time: 10.615 s
[mt_rand 0] Time: 10.948 s
[mt_rand 1] Time: 9.883 s
[mt_rand 2] Time: 10.190 s

seulement 6-9% et non pas 400% comme déclaré.


utilisation à des fins de sécurité

mais si votre application a besoin de beaucoup d'entropie en raison de problèmes de sécurité, vous aurez besoin d'un moyen plus sûr et openssl_random_pseudo_bytes() peut-être la meilleure solution, fait son travail (beaucoup mieux mais plus lent? nous avons besoin de sécurité au-dessus de la vitesse?) en se basant sur les questions liées à openssl.

ni L'un ni l'autre rand() ni mt_rand() sont assez sécuritaires:

Attention Cette fonction ne génère pas cryptographique sécurisé valeurs, et ne devrait pas être utilisé à des fins cryptographiques. Si vous avez besoin d' une valeur cryptographique sécurisée, envisagez d'utiliser random_int(), random_bytes(), ou openssl_random_pseudo_bytes() à la place.

il y a des extensions PHP comme random_compat, mais je ne recommande pas de les utiliser si c'est pas nécessaire.

19
répondu OscarGarcia 2017-05-30 07:22:06

manuel PHP sur mt_rand() déclare:

qui produira des nombres aléatoires quatre fois plus rapides que ce que le libc rand() moyen fournit.

1
répondu Forien 2015-02-27 09:09:38

à partir de PHP 7.1 il y a pas de différence à tous. Rand () est maintenant un alias pour mt_rand ().

Voir http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.rand-srand-aliases

Et plus de détails: https://wiki.php.net/rfc/rng_fixes

1
répondu Bell 2016-12-14 05:46:05



Voici la différence de vitesse pour les deux: -

mt_rand($min, $max)quatre fois plus rapide que rand($min, $max)



La raison en est que,rand($min, $max)libc générateur de nombre aléatoiremt_rand($min, $max)Mersenne Twister qui est quatre fois plus rapide.



espérons que cela résoudra votre doute.

Merci.

-1
répondu PHP Team 2015-02-27 08:45:43

Ils apparaissent à la même vitesse:

function timeit($times, $func) {
    $t = microtime(1);
    while($times--) $func();
    return microtime(1) - $t;
}

echo PHP_OS, " ", phpversion(), "\n";
echo timeit(100000, function() {    rand(0,1000); }), "\n";
echo timeit(100000, function() { mt_rand(0,1000); }), "\n";

résultats pour OSX Mavericks et Virtualbox'ed Ubuntu 11:

Darwin 5.5.19
0.038038969039917
0.033117055892944

Linux 5.3.6-13ubuntu3.10
0.031459093093872
0.031935214996338

si ces mesures sont correctes, le commentaire manuel mentionné ailleurs doit être considéré comme erroné/périmé.

-1
répondu georg 2015-02-27 08:52:58