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
?
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
?
Entropy is stored in
std::mt19937
which means that you will continue the random sequence, but as noted by Steve Jessop it still has some overhead for creating an object. If you expect this function to be called frequently with the same arguments, then you can cachestd::uniform_int_distribution<uint32_t>
objects in a map that usesstd::pair<uint32_t, uint32_t>
as a key.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 implementation2**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 lateroperator()
invocation. So ifmin==0
andmax==1
, then you can get 32 calls tooperator()
on the distribution per call on the generator. That's what thereset()
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.
I generally do the following:
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
, usingtime(NULL)
or some other seed method.