在性能方面,生成随机布尔值的最佳方法是什么?
我需要在性能关键路径上生成随机布尔值.
I need to generate random Boolean values on a performance-critical path.
我为此编写的代码是
std::random_device rd;
std::uniform_int_distribution<> randomizer(0, 1);
const int val randomizer(std::mt19937(rd()));
const bool isDirectionChanged = static_cast<bool>(val);
但不要认为这是最好的方法,因为我不喜欢这样做 static_cast<bool>
.
But do not think that this is the best way to do this as I do not like doing static_cast<bool>
.
在网上我找到了更多的解决方案
On the web I have found a few more solutions
1. std::bernoulli_distribution代码>
2.代码>bool randbool = rand() &1;记得在开头调用srand()
.
2. bool randbool = rand() & 1;
Remember to call srand()
at the beginning.
推荐答案
出于性能的目的,以比例如更少的随机性"为代价.std::mt19937_64
,您可以使用 Xorshift+ 生成 64 位数字然后将这些数字的位用作伪随机布尔值.
For the purpose of performance, at a price of less "randomness" than e.g. std::mt19937_64
, you can use Xorshift+ to generate 64-bit numbers and then use the bits of those numbers as pseudo-random booleans.
引用维基百科:
此生成器是通过 BigCrush 的最快生成器之一
This generator is one of the fastest generators passing BigCrush
详情:http://xorshift.di.unimi.it/.页面中间有一个对比表,显示mt19937_64
慢2倍,系统化.
Details: http://xorshift.di.unimi.it/ . There is a comparison table in the middle of the page, showing that mt19937_64
is 2 times slower and is systematic.
下面是示例代码(真正的代码应该把它封装在一个类中):
Below is sample code (the real code should wrap it in a class):
#include <cstdint>
#include <random>
using namespace std;
random_device rd;
/* The state must be seeded so that it is not everywhere zero. */
uint64_t s[2] = { (uint64_t(rd()) << 32) ^ (rd()),
(uint64_t(rd()) << 32) ^ (rd()) };
uint64_t curRand;
uint8_t bit = 63;
uint64_t xorshift128plus(void) {
uint64_t x = s[0];
uint64_t const y = s[1];
s[0] = y;
x ^= x << 23; // a
s[1] = x ^ y ^ (x >> 17) ^ (y >> 26); // b, c
return s[1] + y;
}
bool randBool()
{
if(bit >= 63)
{
curRand = xorshift128plus();
bit = 0;
return curRand & 1;
}
else
{
bit++;
return curRand & (1<<bit);
}
}
相关文章