What is performance-wise the best way to generate random bools?

前端 未结 9 2198
滥情空心
滥情空心 2020-12-23 21:14

I need to generate random Boolean values on a performance-critical path.

The code which I wrote for this is

std::random_device   rd;
std::uniform_int         


        
9条回答
  •  盖世英雄少女心
    2020-12-23 21:54

    Some quick benchmarks (code):

       647921509 RandomizerXorshiftPlus
       821202158 BoolGenerator2 (reusing the same buffer)
      1065582517 modified Randomizer
      1130958451 BoolGenerator2 (creating a new buffer as needed)
      1140139042 xorshift128plus
      2738780431 xorshift1024star
      4629217068 std::mt19937
      6613608092 rand()
      8606805191 std::bernoulli_distribution
     11454538279 BoolGenerator
     19288820587 std::uniform_int_distribution
    

    For those who want ready-to-use code, I present XorShift128PlusBitShifterPseudoRandomBooleanGenerator, a tweaked version of RandomizerXorshiftPlus from the above link. On my machine, it is about as fast as @SergeRogatch's solution, but consistently about 10-20% faster when the loop count is high (≳100,000), and up to ~30% slower with smaller loop counts.

    class XorShift128PlusBitShifterPseudoRandomBooleanGenerator {
    public:
      bool randBool() {
        if (counter == 0) {
          counter = sizeof(GeneratorType::result_type) * CHAR_BIT;
          random_integer = generator();
        }
        return (random_integer >> --counter) & 1;
      }
    
    private:
      class XorShift128Plus {
      public:
        using result_type = uint64_t;
    
        XorShift128Plus() {
          std::random_device rd;
          state[0] = rd();
          state[1] = rd();
        }
    
        result_type operator()() {
          auto x = state[0];
          auto y = state[1];
          state[0] = y;
          x ^= x << 23;
          state[1] = x ^ y ^ (x >> 17) ^ (y >> 26);
          return state[1] + y;
        }
    
      private:
        result_type state[2];
      };
    
      using GeneratorType = XorShift128Plus;
    
      GeneratorType generator;
      GeneratorType::result_type random_integer;
      int counter = 0;
    };
    

提交回复
热议问题