Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I keep the random distribution object instance or can I always recreate it?

Tags:

c++

random

c++11

I have this code:

static std::mt19937 rnd;

// ...

static uint32_t rndInt(uint32_t min, uint32_t max) {
    return std::uniform_int_distribution<uint32_t>(min,max)(rnd);
}

Is that good practice or should I store the uniform_int_distribution?

like image 633
Albert Avatar asked Dec 08 '11 15:12

Albert


2 Answers

I doubt that the distribution object is expensive to create and destroy, although I suppose it might do slightly more than just store the parameters min,max. It might precalculate some useful values based on the parameters, for instance in the obvious implementation 2**32 % (max-min+1) is the number of different values from the generator that would be discarded and re-tried.

In principle, a distribution object is allowed to store inside it some bits of entropy that were drawn from the generator on a previous call to operator(), but not needed. Those bits could be used for a later operator() invocation. So if min==0 and max==1, then you can get 32 calls to operator() on the distribution per call on the generator. That's what the reset() function is about, to clear this state.

So if you use the same min/max values repeatedly, then technically you're wasting random bits by using a new distribution each time -- you could perhaps end up with fewer calls to the engine than if you kept the distribution object around. But I doubt it matters, especially since MT is fast.

like image 169
Steve Jessop Avatar answered Oct 15 '22 09:10

Steve Jessop


I generally do the following:

std::uniform_int_distribution<uint32_t> distrib(16, 97);

Then you may call distrib(rnd) multiple times without regenerating the distribution each time.

The way you are performing the operation forces the distribution to be recreated each time you make the call. If your min and max params are fixed, then create a distribution object and call it, otherwise, stay with what you have.

BTW, I would seed rnd, using time(NULL) or some other seed method.

like image 34
codewiz51 Avatar answered Oct 15 '22 10:10

codewiz51