在性能方面,生成随机布尔值的最佳方法是什么?

2022-01-19 00:00:00 random boolean c++ c++11 c++14

我需要在性能关键路径上生成随机布尔值.

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);
    }
}

相关文章