Quelle est la différence entre l'utilisation de mt_Rand($min, $max)
et Rand($min, $max)
sur la vitesse?
Depuis PHP 7.1 mt_Rand
A complètement remplacé Rand
et Rand
a été créé un alias pour mt_Rand
. La réponse ci-dessous se concentre sur les différences entre les deux fonctions pour les anciennes versions et les raisons de l'introduction de mt_Rand
.
mt_Rand
A été introduit!La fonction Rand
existait bien avant mt_Rand
, Mais elle était profondément défectueuse. A 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 nombres qui ont été 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 ce qu'était la graine Rand
, et avec elle, vous pouvez prédire les prochains nombres aléatoires. Il existe des outils qui font cela, alors google un peu et testez-le.
Il y a aussi un problème avec Rand
montrant rapidement des motifs dans ses nombres aléatoires comme démontré ici . Un problème mt_Rand
Semble aussi beaucoup mieux résoudre.
mt_Rand
Utilise un meilleur algorithme de randomisation (Mersenne Twist), qui nécessite de connaître plus de nombres aléatoires avant de déterminer la graine et est plus rapide. Cela ne signifie pas que mt_Rand
Est, par définition, plus rapide que Rand
est , 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 les performances de la fonction, comme l'ont démontré d'autres réponses ici.
Quoi qu'il en soit, jetez un œil à le mt_srand
et le srand
docs . Je suis sûr qu'ils contiendront plus d'informations
Si l'algorithme de mt_Rand
Se traduit par une augmentation des performances, c'est parfait 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
!
Rand()
etsrand()
sont désormais des alias pourmt_Rand()
etmt_srand()
, respectivement. Cela signifie que le les sorties des fonctions suivantes ont été modifiées:Rand()
,shuffle()
,str_shuffle()
etarray_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 .
L'utilisation de Rand()
n'est pas une mauvaise pratique si elle n'est pas utilisée à des fins de sécurité, j'utilise généralement Rand()
(habitude?).
Si vous avez besoin d'une énorme quantité de nombres aléatoires, vous aurez besoin de mt_Rand
À la place Rand
. mt_Rand
A une période de 219937 - 1, bien meilleur que Rand
(232). Jetez un œil à cet article sur la génération de motifs graphiques en utilisant Rand
et mt_Rand
.
périodicité et entropie sont les seules raisons d'utiliser mt_Rand()
à la place Rand()
et non la sécurité ou des améliorations de vitesse.
Mathématiquement mt_Rand
Ont plus entropie et plus périodicité que Rand
(219937-1 contre 232).
Si vous avez besoin de quelques nombres aléatoires et que la sécurité n'est pas un problème, Rand
fera le travail (obtenez un nombre aléatoire pour décider de lancer un processus de nettoyage).
En pratique, il n'y a pas beaucoup de différence de vitesse entre les deux fonctions (peut-être à cause de la surcharge du wrapper PHP?).
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 (machine plus lente):
$ 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 400% comme revendiqué.
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écurisé et openssl_random_pseudo_bytes()
est probablement la meilleure solution, fait son travail (bien mieux mais plus lentement ? nous avons besoin de sécurité sur la vitesse?) en s'appuyant sur les problèmes liés à openssl .
Ni Rand()
ni mt_Rand()
ne sont suffisamment sûrs :
Attention Cette fonction ne génère pas de valeurs sécurisées cryptographiquement et ne doit pas être utilisée à des fins cryptographiques. Si vous avez besoin d'une valeur cryptographiquement sécurisée, pensez à utiliser à la place
random_int()
,random_bytes()
ouopenssl_random_pseudo_bytes()
.
Il y a PHP extensions comme random_compat
, mais je ne recommande pas de les utiliser si ce n'est pas nécessaire.
Depuis PHP 7.1 il n'y a aucune différence . 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
Le manuel PHP sur mt_Rand()
indique qu'il:
qui produira des nombres aléatoires quatre fois plus rapidement que ce que fournit la libc moyenne Rand ().