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

前端 未结 9 2200
滥情空心
滥情空心 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 22:00

    I would prefill a (long enough) (circular) buffer of 64bit random values, and then take very quickly one bit at a time when in need of a boolean random value

    #include 
    
    class BoolGenerator {
      private:
      const int BUFFER_SIZE = 65536;
      uint64_t randomBuffer[BUFFER_SIZE];
      uint64_t mask;
      int counter;
    
      void advanceCounter {
        counter++;
        if (counter == BUFFER_SIZE) {
            counter = 0;
        }
      }
    
      public:
      BoolGenerator() {
        //HERE FILL YOUR BUFFER WITH A RANDOM GENERATOR
        mask = 1;
        counter = 0;
      }
    
      bool generate() {
        mask <<= 1;
        if (!mask) { //After 64 shifts the mask becomes zero
            mask = 1;//reset mask
            advanceCounter();//get the next value in the buffer
        }
        return randomBuffer[counter] & mask;
      }
    }
    

    Of course the class can be made general to the buffer size, the random generator, the base type (doesn't necessarily have to be uint64_t) etc.


    Accessing the buffer only once every 64 calls:

    #include  //...and much more
    
    class BoolGenerator {
      private:
      static const int BUFFER_SIZE = 65536;
      uint64_t randomBuffer[BUFFER_SIZE];
      uint64_t currValue;
      int bufferCounter;
      int bitCounter;
    
      void advanceBufferCounter() {
        bufferCounter++;
        if (bufferCounter == BUFFER_SIZE) {
            bufferCounter = 0;
        }
      }
    
      void getNextValue() {
          currValue = randomBuffer[bufferCounter];
          bitCounter = sizeof(uint64_t) * 8;
          advanceBufferCounter();
      }
    
      //HERE FILL YOUR BUFFER WITH A RANDOM GENERATOR
      void initializeBuffer() {
      //Anything will do, taken from here: http://stackoverflow.com/a/19728404/2436175
          std::random_device rd;
          std::mt19937 rng(rd());
          std::uniform_int_distribution uni(0,std::numeric_limits::max());
          for (int i = 0; i < BUFFER_SIZE; i++ ) {
              randomBuffer[i] = uni(rng);
          }
      }
    
      public:
      BoolGenerator() {
          initializeBuffer();
          bufferCounter = 0;
          getNextValue();
      }
    
      bool generate() {
          if (!bitCounter) {
               getNextValue();
          }
          //A variation of other methods seen around
          bitCounter--;
          bool retVal = currValue & 0x01;
          currValue >>= 1;
          return retVal;
      }
    };
    

提交回复
热议问题