我有这段代码:
static std::mt19937 rnd;
// ...
static uint32_t rndInt(uint32_t min, uint32_t max) {
return std::uniform_int_distribution<uint32_t>(min,max)(rnd);
}
这是一种好的做法,还是应该存储uniform_int_distribution
?
答案 0 :(得分:9)
我怀疑分发对象的创建和销毁成本很高,尽管我认为它可能只是存储参数min,max
。它可能会根据参数预先计算一些有用的值,例如在明显的实现中2**32 % (max-min+1)
是生成器中将被丢弃和重新尝试的不同值的数量。
原则上,允许分发对象在其中存储一些熵,这些熵是在先前调用operator()
时从生成器中提取的,但不是必需的。这些位可用于稍后的operator()
调用。因此,如果min==0
和max==1
,那么您可以在生成器上每次调用的分配上对operator()
进行32次调用。这就是reset()
函数的用途,以清除这种状态。
因此,如果您重复使用相同的最小值/最大值,那么从技术上讲,每次使用新的分布都会浪费随机位 - 与保留分发对象相比,最终可能会减少对引擎的调用周围。但我怀疑这很重要,特别是因为MT很快。
答案 1 :(得分:1)
我通常会做以下事情:
std::uniform_int_distribution<uint32_t> distrib(16, 97);
然后,您可以多次调用distrib(rnd)
,而不必每次都重新生成分发。
执行操作的方式会强制每次拨打电话时重新创建分发。如果你的最小和最大参数是固定的,那么创建一个分配对象并调用它,否则,保持你拥有的。
BTW,我会使用rnd
或其他种子方法播种time(NULL)
。
答案 2 :(得分:0)
熵存储在std::mt19937
中,这意味着您将继续随机序列,但正如Steve Jessop所指出的,它仍然有一些创建对象的开销。如果您希望使用相同的参数频繁调用此函数,则可以在使用std::uniform_int_distribution<uint32_t>
作为键的映射中缓存std::pair<uint32_t, uint32_t>
个对象。