Php mt_rand()和rand()之间的差异
使用Php mt_rand()和rand()之间的差异,php,performance,optimization,random,Php,Performance,Optimization,Random,使用mt_rand($min,$max)和rand($min,$max)关于速度的区别是什么?PHP手册说明: 这将产生比libc rand()平均值快四倍的随机数 以下是两者在速度上的差异:-mt\u rand($min,$max)比rand($min,$max)快四倍原因是,rand($min,$max)使用libc随机数生成器而mt rand($min,$max)使用Mersenne捻线机,速度快四倍。希望它能解决您的疑问。谢谢。它们的速度似乎相等: function timeit($ti
mt_rand($min,$max)
和rand($min,$max)
关于速度的区别是什么?PHP手册说明:
这将产生比libc rand()平均值快四倍的随机数
以下是两者在速度上的差异:-
mt\u rand($min,$max)
比rand($min,$max)
快四倍原因是,rand($min,$max)
使用libc随机数生成器而mt rand($min,$max)
使用Mersenne捻线机,速度快四倍。希望它能解决您的疑问。
谢谢。它们的速度似乎相等:
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的Ubuntu 11的结果:
Darwin 5.5.19
0.038038969039917
0.033117055892944
Linux 5.3.6-13ubuntu3.10
0.031459093093872
0.031935214996338
如果这些措施是正确的,其他地方提到的手动注释应被视为错误/过时。更新
因为PHP7.1mt_rand
已经完全取代了rand
,并且rand
成为mt_rand
的别名。下面的答案集中在旧版本的两个函数之间的差异,以及引入mt_rand
的原因
速度并不是引入mt_rand的原因!
rand
函数在mt_rand
之前就已经存在,但它存在着严重的缺陷。一个PRNG必须得到一些熵,一个从中生成随机数序列的数。如果您打印出由rand()
生成的十个数字的列表,如下所示:
for ($i=0;$i<10;++$i)
echo rand(), PHP_EOL;
对于($i=0;$i更新(PHP7.1):
这意味着以下函数的输出有更改:rand()
,shuffle()
,str\u shuffle()
,和array\u rand()
这意味着自7.1版以来,它们之间没有实际区别,因为
在PHP 7.1之前:
使用rand()
不是一个坏习惯,如果不是出于安全目的,我通常使用rand()
(习惯?)
如果您需要大量随机数,则需要mt_rand
而不是rand
mt_rand
的周期为219937− 1,远远优于rand
(232)。请查看有关使用rand
和mt\u rand
生成图形图案的信息
和是使用mt_rand()
代替rand()
的唯一原因,而不是安全性或速度改进。
从数学上讲,mt_rand
的数量大于rand
(219937−1对232)
如果您需要一些随机数,并且安全性不是问题,rand
将完成这项工作(获取一个随机数以决定启动清理过程)
测试速度改进
实际上,这两个函数之间的速度差别不大(可能是因为PHP⇔C包装器开销?)
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);
}
$ 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 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
PHP5.4.45中的测试(较慢的机器):
<?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 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 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
只有6-9%,而不是声称的400%
用于安全目的
但是,如果您的应用程序因为安全问题而需要大量的熵,那么您将需要一种更安全的方式,并且可能是最好的解决方案,它是否工作正常(更好但更慢?我们需要的是速度更高的安全性?)
两者都不够安全:
注意此函数不会生成加密安全的
值,并且不应用于加密目的。如果需要
一个加密的安全值,考虑使用<代码> RealthIn()/<代码>
random\u bytes()
,或openssl\u random\u pseudo\u bytes()
有类似的PHP扩展,但我不建议在没有必要的情况下使用它们。从PHP7.1开始,没有任何区别。.rand()现在是mt_rand()的别名
看
还有更多细节:那么为什么兰德()存在?@marveylabrand()
是PHP中很长一段时间以来的标准语言构造(可能是从C
语言移植而来)。mt\u rand()
据我所知有点新。这就是为什么mt\u rand()
被称为better rand
)@福林:你忘记了过去的rand
与mt_rand
=>相比的问题,例如,从输出中推断种子的容易程度example@Forien:请再次检查文档,据说更快的不是mt\u rand
功能,它使用的算法比平均的libcrand
函数快。这并不意味着这种速度差异将转化为PHP中的性能差异。。。它只说明PRNG生成数字的速度更快,仅此而已less@EliasVanOotegem是的,这意味着系统“更快”,而不是PHP。但是,如果您看不到PHP速度的差异,但是具有更好的分布,并且对服务器上的系统施加的压力更小,那么为什么不使用它呢?mt_rand
速度快了四倍,这是一个可怕的笼统说法,很可能已经过时。“平均”libcrand
自从那句话被添加到PHP文档中以来,可能已经改变了100倍。。。此外,mt_rand
不是因为速度原因而添加的,而是因为旧的rand
PRNG中固有的缺陷而添加的。速度提高从来都不是mt_rand
的主要原因,这似乎是每个人都忘记了的。@EliasVanOotegem:事实上,整个辩论对我来说似乎无足轻重。对于“弱”随机性(“洗牌牌”),使用rand或mt并不重要,在严肃的应用(密码学)中,两者都不应该使用。你是对的。这是一场毫无意义的辩论。所有的答案都没有提到更好的mt_rand