mt_rand() 和兰特()之间的区别速度不是为什么被引入!mt_rand mt_rand引入是为了修复 中存在的问题!rand更新 (PHP 7.1):在 PHP 7.1 之前的版本:测试速度改进用于安全目的
使用和速度有什么区别?mt_rand($min, $max)
rand($min, $max)
使用和速度有什么区别?mt_rand($min, $max)
rand($min, $max)
由于 PHP 7.1 已被完全取代,并成为 .下面的答案重点介绍旧版本的两个函数之间的差异,以及引入的原因。mt_rand
rand
rand
mt_rand
mt_rand
mt_rand
这个函数在很久以前就已经存在了,但它有很深的缺陷。PRNG必须获得一些熵,这是一个数字,从中它生成一个随机数序列。如果您打印出由以下方式生成的十个数字的列表:rand
mt_rand
rand()
for ($i=0;$i<10;++$i)
echo rand(), PHP_EOL;
输出可用于计算种子是什么,并且通过它,您可以预测下一个随机数。有一些工具可以做到这一点,所以谷歌一下并测试它。rand
还有一个问题,即相对快速地显示其随机数中的模式,如此处所示。问题似乎也解决得更好。rand
mt_rand
mt_rand
使用更好的随机化算法(Mersenne Twist),在确定种子之前需要更多的随机数,并且速度更快。这并不意味着根据定义,mt_rand
比兰特
快,这只意味着数字的生成方式更快,并且似乎对函数的性能没有实际影响,正如这里的其他答案所证明的那样。
无论哪种方式,看看mt_srand
和srand
文档。我相信它们会包含更多信息
如果 的算法转化为性能的提高,那么这对你来说很好,但这是一个令人高兴的巧合。TL;TR:mt_rand
mt_rand
引入是为了修复 中存在的问题!rand
rand()
和srand()
现在分别成为mt_rand()
和mt_srand() 的
别名。这意味着以下函数的输出具有更改:、 、 和 。rand()
shuffle()
str_shuffle()
array_rand()
这意味着从7.1版本开始,它们之间没有实际区别,因为rand
调用mt_rand
内部。
如果不用于安全目的,使用不是一种不好的做法,我通常使用(习惯?rand()
rand()
如果你需要大量的随机数,你将需要代替。 周期为 219937 − 1,远优于 (232)。请看这篇关于使用 和 生成图形模式的文章。mt_rand
rand
mt_rand
rand
rand
mt_rand
周期性和熵是使用mt_rand()
而不是rand()
的唯一原因,而不是安全性或速度改进。
在数学上比(219937−1 vs. 232)具有更多的熵和更大的周期性。mt_rand
rand
如果你需要几个随机数并且安全性不是问题,就会做这项工作(获取一个随机数来决定触发清理过程)。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 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
PHP 5.4.45 中的测试(较慢的机器):
$ 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%。
但是,如果您的应用程序因为安全问题而需要很多熵,您将需要一种更安全的方式,并且openssl_random_pseudo_bytes()
可能是最佳解决方案,它的工作是否有效(要好得多但速度更快?我们需要安全性而不是速度?)依赖于opensl相关的问题。
rand()
和 mt_rand()
都不够安全:
谨慎此函数不生成加密安全值,并且不应用于加密目的。如果需要加密安全的值,请考虑改用 、 或 。
random_int()
random_bytes()
openssl_random_pseudo_bytes()
有像random_compat
这样的PHP扩展,但是如果没有必要,我不建议使用它们。