Каковы преимущества использования uniform_int_distribution против операции модуля?
Согласно следующим результатам, генерирование единичных случайных чисел между двумя числами с использованием операции %
почти в 3 раза быстрее, чем при использовании std::uniform_int_distribution
: есть ли веские основания использовать 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
Ответы
Ответ 1
При использовании modulo (%
) вы получите статистическое отклонение, чтобы отобразить диапазон, например. rand()
к другому интервалу.
Например, предположим, что rand()
равномерно отображает (без смещения) на [0, 32767]
и вы хотите отобразить на [0,4]
выполнение rand() % 5
. Тогда значения 0, 1 и 2 будут в среднем получаться 6554 из 32768 раз, но значения 3 и 4 только 6553 раз (так что 3 * 6554 + 2 * 6553 = 32768).
Уклон небольшой (0,01%), но в зависимости от вашего приложения, которое может оказаться фатальным. Смотрите, что Стефан Т. Лававей говорит " rand() считается вредным" для более подробной информации.