在C++中生成随机数的计算成本有多高
How computationally expensive is generating a random number in C++?
我正在考虑的方法是从范围生成随机整数的答案。
#include <random>
std::random_device rd; // only used once to initialise (seed) engine
std::mt19937 rng(rd()); // random-number engine used (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(min,max); // guaranteed unbiased
auto random_integer = uni(rng);
我也愿意对srand(time(NULL))
使用rand()
方法。
这些方法有多昂贵?一个比另一个快得多吗?
性能在很大程度上取决于您使用的生成器(这又在很大程度上取决于您所需数字的质量)。
例如,std::mt19937
比std::random_device
快得多,但它会产生伪随机数。如果您不需要加密安全的随机数,这对于大多数目的来说都很好。但即使你这样做了,random_device
也可以在我的机器上以大约 50 MB/秒的速度产生原始熵——你真正需要多少随机性?(如果需要,mt19937
生成的数量级比这多几个数量级)。
避免rand()
。它只是具有非常差的特性和非常低的周期。
另见兰德被认为是有害的。
我可以写性能取决于实现和硬件,但它既正确又无用。 性能的一个例子会更有用。
戴尔Latitude E7240笔记本电脑(2013),Linux,g++ 4.8.4和-O3标志:
#include <cstdlib>
#include <iostream>
int main(int argc, const char** argv) {
const bool bPlain = (argv[1][0] == '-');
if (bPlain)
argv++;
int n = atoi(argv[1]);
int sum = 0;
if (bPlain)
for (int i=0; i<n; i++)
sum |= i;
else
for (int i=0; i<n; i++)
sum |= rand();
// To prevent the compiler from optimizing away the loop
if (sum == 0)
std::cout << sum << std::endl;
}
[~/CPP] time ./randbm 1000000000
9.049u 0.000s 0:09.05 99.8% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm 1000000000
9.059u 0.000s 0:09.06 99.8% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm 1000000000
9.040u 0.008s 0:09.05 99.8% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm - 1000000000
0.192u 0.000s 0:00.20 95.0% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm - 1000000000
0.172u 0.000s 0:00.18 94.4% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm - 1000000000
0.185u 0.004s 0:00.20 90.0% 0+0k 0+0io 0pf+0w
因此,在这种特殊情况下,对 rand() 的一次调用大约需要 9 纳秒,而一次循环迭代大约需要 0.2 纳秒。
使用random
速度较慢。添加#include <random>
并将代码的相关部分替换为:
std::random_device rd; // only used once to initialise (seed) engine
std::mt19937 rng(rd()); // random-number engine used (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(0, 1048575);
if (bPlain)
for (int i=0; i<n; i++)
sum |= i;
else
for (int i=0; i<n; i++)
sum |= uni(rng);
我们得到(注意我们运行 108 次,而不是 109):
[~/CPP] time ./randbm2 100000000
2.478u 0.003s 0:02.49 99.1% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm2 100000000
2.471u 0.004s 0:02.47 100.0% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm2 100000000
2.445u 0.007s 0:02.48 98.3% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm2 100000000
2.497u 0.004s 0:02.50 99.6% 0+0k 0+0io 0pf+0w
[~/CPP] time ./randbm2 100000000
2.482u 0.011s 0:02.49 100.0% 0+0k 0+0io 0pf+0w
以这种方式生成随机数大约需要 25 纳秒。 然而,uni
与rand()
不同,也把数字插入到区间中。
额外的工作重要吗?不。例如,如果您这样做
sum |= (rand() % 1048576);
时间从 9 纳秒增加到 9.5 纳秒。 如果数字不是 2 的幂,例如
sum |= (rand() % 1000000);
这需要 10 纳秒。 将数字插入区间的其他合理方法需要大致相同的时间。
因此,对于一种特定的配置,rand()
本身大约需要 9 纳秒; 加上将随机数插入间隔,大约需要 9.5-10 纳秒; std::mt19937
uniform_int_distribution<int>
大约需要 25 纳秒。
我希望你不是那些将纳秒与微秒混淆的人之一!
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 递归函数计算序列中的平方和(并输出过程)
- 整数不会重复超过随机数
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 类似枚举的计算常量
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 如何将随机数组值一起添加到另一个数组中,然后在计算出现的值时显示它们?C++
- 在C++中生成随机数的计算成本有多高