根据以下结果,使用 %
运算在两个数字之间生成均匀随机整数几乎比使用 std::uniform_int_distribution
快 3 倍:有什么好的理由使用 std::uniform_int_distribution
?
代码:
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <random>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define N 100000000
int main()
{
clock_t tic,toc;
for(int trials=0; trials<3; trials++)
{
cout<<"trial: "<<trials<<endl;
// uniform_int_distribution
{
int res = 0;
mt19937 gen(1);
uniform_int_distribution<int> dist(0,999);
tic = clock();
for(int i=0; i<N; i++)
{
int r = dist(gen);
res += r;
res %= 1000;
}
toc = clock();
cout << "uniform_int_distribution: "<<(float)(toc-tic)/CLOCKS_PER_SEC << endl;
cout<<res<<" "<<endl;
}
// simple modulus operation
{
int res = 0;
mt19937 gen(1);
tic = clock();
for(int i=0; i<N; i++)
{
int r = gen()%1000;
res += r;
res %= 1000;
}
toc = clock();
cout << "simple modulus operation: "<<(float)(toc-tic)/CLOCKS_PER_SEC << endl;
cout<<res<<" "<<endl;
}
cout<<endl;
}
}
输出:
trial: 0
uniform_int_distribution: 2.90289
538
simple modulus operation: 1.0232
575
trial: 1
uniform_int_distribution: 2.86416
538
simple modulus operation: 1.01866
575
trial: 2
uniform_int_distribution: 2.94309
538
simple modulus operation: 1.01809
575
最佳答案
当您使用模数 (%
) 映射例如的范围时,您将得到 统计偏差 rand()
到另一个区间。
例如假设 rand()
统一映射(无偏差)到 [0, 32767]
并且您想映射到 [0,4]
做 rand() % 5
。那么值 0、1 和 2 将平均产生 32768 次中的 6554 次,但值 3 和 4 仅产生 6553 次(因此 3 * 6554 + 2 * 6553 = 32768)。
偏差很小 (0.01%),但取决于您的应用程序,这可能是致命的。观看 Stephan T. Lavavej 的演讲“rand() considered harmful”了解更多详情。
关于c++ - 使用 uniform_int_distribution 与模数运算有什么优势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32860654/