使用mt_rand($min, $max)
和rand($min, $max)
关于速度有什么区别?
答案 0 :(得分:45)
由于PHP 7.1 mt_rand
已完全取代rand
,因此rand
成为mt_rand
的别名。下面的答案重点介绍旧版本的两个功能之间的差异,以及引入mt_rand
的原因。
mt_rand
的原因! rand
功能在mt_rand
之前存在,但它存在严重缺陷。 PRNG必须得到一些熵,一个数字,从中产生一系列随机数。如果您打印出由rand()
生成的十个数字的列表,如下所示:
for ($i=0;$i<10;++$i)
echo rand(), PHP_EOL;
输出可用于计算rand
种子的含义,并且可以使用它来预测下一个随机数。有一些工具可以做到这一点,所以谷歌稍微测试一下。
rand
还存在一个问题,即相对较快地快速显示其随机数as demonstrated here中的模式。问题mt_rand
似乎也解决得更好。
mt_rand
使用更好的随机化算法(Mersenne Twist),在确定种子和更快之前,需要更多的随机数。 这并不意味着mt_rand
根据定义比rand
更快,这只意味着生成数字的方式更快,并且似乎对功能的表现没有实际影响,正如此处的其他答案所证明的那样
无论哪种方式,请查看the mt_srand
和the srand
docs。我确定他们会包含更多信息
如果mt_rand
的算法在性能上有所提升,那么这对你来说很棒,但这是一个快乐的巧合。 TL; TR:
mt_rand
来修复rand
中存在的问题!答案 1 :(得分:24)
rand()
andsrand()
have now been made aliases tomt_rand()
andmt_srand()
, respectively.这意味着以下功能的输出有所变化:rand()
,shuffle()
,str_shuffle()
和array_rand()
。
这意味着自7.1版以来,两者之间没有实际区别,因为rand
calls mt_rand
internally。
如果不将rand()
用于安全目的,那么使用rand()
通常不会使用mt_rand
(习惯?)。
如果您需要大量随机数,则需要rand
而不是mt_rand
。 rand
的周期为2 19937 - 1,远远优于rand
(2 32 )。使用mt_rand
和mt_rand()
了解有关图形模式生成的this article。
Periodicity和entropy是使用rand()
代替mt_rand
而不是安全或速度提升的唯一原因。
数学上rand
的{{3}}多entropy,periodicity比rand
更高(2 19937 -1 vs. 2 32 < / SUP>)。
如果您需要一些随机数并且安全性不是问题,<?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);
}
将完成工作(获取一个随机数来决定启动清理过程)。
在实践中,两个函数之间的速度差别不大(可能是因为PHP⇔C包装器开销?)。
PHP测试代码:
$ 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
PHP 7.0.19中的测试:
$ 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
在PHP 5.4.45(较慢的机器)中进行测试:
random_int()
只有6-9%,而不是400%。
但是如果您的应用程序需要大量的熵,因为安全性问题,您需要一种更安全的方式,openssl_random_pseudo_bytes()
可能是最好的解决方案,它的工作(更好但更慢?我们需要安全性)超速?)relying on openssl related issues。
rand()
nor mt_rand()
都不够安全:
警告此功能不会生成加密安全 值,不应用于加密目的。如果你需要 加密安全值,请考虑使用
random_bytes()
,openssl_random_pseudo_bytes()
,或{{1}}。
有random_compat
之类的PHP扩展程序,但如果没有必要,我建议不要使用它们。
答案 2 :(得分:1)
mt_rand()
上的PHP手册指出:
将产生比平均libc rand()提供的速度快四倍的随机数。
答案 3 :(得分:1)
从PHP 7.1开始,完全没有区别。 rand()现在是mt_rand()的别名。
请参阅http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.rand-srand-aliases
答案 4 :(得分:-1)
以下是两者的速度差异: - 与mt_rand($min, $max)
相比,rand($min, $max)
快<4> >
原因是,rand($min, $max)
使用 libc随机数生成器,而mt_rand($min, $max)
使用 Mersenne Twister ,速度提高了四倍。<希望它能解决你的疑问。
谢谢。
答案 5 :(得分:-1)
它们的速度似乎相同:
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";
OSX Mavericks和VirtualBox'ed Ubuntu 11的结果:
Darwin 5.5.19
0.038038969039917
0.033117055892944
Linux 5.3.6-13ubuntu3.10
0.031459093093872
0.031935214996338
如果这些措施是正确的,那么其他地方提到的手工评论应被视为错误/过时。