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.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;
对于($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()的别名


还有更多细节:

那么为什么兰德()存在?@marveylab
rand()
是PHP中很长一段时间以来的标准语言构造(可能是从
C
语言移植而来)。
mt\u rand()
据我所知有点新。这就是为什么
mt\u rand()
被称为
better rand
)@福林:你忘记了过去的
rand
mt_rand
=>相比的问题,例如,从输出中推断种子的容易程度example@Forien:请再次检查文档,据说更快的不是
mt\u rand
功能,它使用的算法比平均的libc
rand
函数快。这并不意味着这种速度差异将转化为PHP中的性能差异。。。它只说明PRNG生成数字的速度更快,仅此而已less@EliasVanOotegem是的,这意味着系统“更快”,而不是PHP。但是,如果您看不到PHP速度的差异,但是具有更好的分布,并且对服务器上的系统施加的压力更小,那么为什么不使用它呢?
mt_rand
速度快了四倍,这是一个可怕的笼统说法,很可能已经过时。“平均”libc
rand
自从那句话被添加到PHP文档中以来,可能已经改变了100倍。。。此外,
mt_rand
不是因为速度原因而添加的,而是因为旧的
rand
PRNG中固有的缺陷而添加的。速度提高从来都不是mt_rand
的主要原因,这似乎是每个人都忘记了的。@EliasVanOotegem:事实上,整个辩论对我来说似乎无足轻重。对于“弱”随机性(“洗牌牌”),使用rand或mt并不重要,在严肃的应用(密码学)中,两者都不应该使用。你是对的。这是一场毫无意义的辩论。所有的答案都没有提到更好的
mt_rand