我是否应该保留随机分布对象实例,或者我可以总是重新创建它
Should I keep the random distribution object instance or can I always recreate it?
我有这样的代码:
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
?
我怀疑创建和销毁分布对象的成本是否很高,尽管我认为它可能比仅仅存储参数min,max
要稍微高一些。它可以根据参数预先计算出一些有用的值,例如,在明显的实现中,2**32 % (max-min+1)
是来自生成器的不同值的数量,这些值将被丢弃并重新尝试。
原则上,允许分布对象在其内部存储一些熵位,这些熵位是在以前调用operator()
时从生成器中提取的,但不是必需的。这些位可以用于以后的operator()
调用。因此,如果min==0
和max==1
,那么您可以在生成器上每次调用分布上的operator()
调用32次。这就是reset()
函数的作用,清除这种状态。
所以如果你重复使用相同的min/max值,那么从技术上讲,你每次使用一个新的分布都是在浪费随机比特——你可能会比保留分布对象更少地调用引擎。但我怀疑这有什么关系,特别是因为MT速度很快。
我通常这样做:
std::uniform_int_distribution<uint32_t> distrib(16, 97);
那么您可以多次调用distrib(rnd)
,而不必每次重新生成分布。
您执行操作的方式强制在每次调用时重新创建分布。如果您的最小和最大参数是固定的,那么创建一个分布对象并调用它,否则,保持现有的
顺便说一句,我会用time(NULL)
或其他方法播种rnd
。
熵存储在std::mt19937
中,这意味着您将继续随机序列,但正如Steve Jessop所指出的,它仍然有一些创建对象的开销。如果您希望使用相同的参数频繁调用此函数,那么您可以在使用std::pair<uint32_t, uint32_t>
作为键的映射中缓存std::uniform_int_distribution<uint32_t>
对象。
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 如何使用CLion在Mac上创建一个新的.txt文件
- C++:继续创建新的变量可以吗
- 如何使用新运算符跟踪在循环中创建的 QLabel
- C++ 如何在将新对象分配给另一个对象时创建新对象
- C++ 警告:将新创建的 gsl::owner<> 分配给非所有者
- 重用对象与创建新对象
- C++,创建新对象时类的对象更改
- 将一个 QWidget 链接到另一个新创建的 QWidget
- 使用Visual Studio在虚幻引擎中创建一个新的类c ++给了我太多的错误
- cout 新创建的对象引发运行时错误
- 使用新运算符C++创建多维数组的简单方法
- C 矢量元素擦除与新向量创建
- 如何使用安置新操作员创建对象数组
- 我如何在参考上使用数据成员而不使用新关键字创建对象
- 通过使用新操作员创建对象会导致未解决的外部符号错误C FTGL
- 使用新关键字创建的C 对象不会呈现;在堆栈上创建的对象确实可以
- 将 QFile::copy 创建创建文件的副本或将内容从一个文件移动到另一个文件
- 部分模板绑定,将新模板创建为类型
- 管理用新char*创建但用自定义分配器分配给std::vector元素的内存块