初始化随机生成器的最佳位置
Best place to initialise random generator
在我的程序中,我经常使用随机数生成器。我相信一般的规则是,你应该将事物定义为靠近它们被"调用"的地方,但这对随机数生成器也适用吗?
例如,在我的代码中,我可以选择:
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(-2147483647, 2147483646);
lots of code
for (i = 0; i < 10000; i++)
{
variable x = uni(rng);
}
或
lots of code
for (i = 0; i < 10000; i++)
{
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(-2147483647, 2147483646);
variable x = uni(rng);
}
我想说第一个方法更快,但由于阅读了许多线程,我有点困惑,在这些线程中,它总是把所有东西都放在离调用它的地方尽可能近的地方。
在这种情况下,在循环之外创建RNG要好得多:
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(-2147483647, 2147483646);
for (i = 0; i < 10000; i++)
{
variable x = uni(rng);
}
这与性能关系不大(尽管它可能也会表现得更好)。原因与正确性有关:
每次通过循环初始化一个新的随机序列,只读取一个值。相反,您应该只初始化一次序列,并从中消耗许多值。在循环外初始化,在循环内消耗。
在性能方面,从std::random_device
读取比从诸如std::mt19937
之类的PRNG获取下一个值慢得多。在循环之外只做一次,将节省大量时间。此外,std::mt19937
PRNG具有大的状态(624个整数)。它根据传递给其构造函数的值生成这个初始状态。同样,只做一次会让你的表现得到提升。
当然,在循环外初始化的优点是也是标准RNG的正确使用模型。
原因是,当您将随机生成器定义定位在代码顶部时,它们将变为全局的,并且当您第一次点击"Run"按钮时,它们会自动定义。如果你在多个地方使用这些变量,这可能是最好的主意。但如果你没有,你就不需要它。因为在某些情况下,他们甚至可能不会打电话。无论如何,这个建议是针对类或方法用法的。
然而,据我所见,你将在for循环中使用这个数字,这将导致你的计算机在低于代码的情况下运行1000次。
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(-2147483647, 2147483646);
这是不必要的,也是无用的。我相信您的第一个代码在性能方面会更好地工作。
相关文章:
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 如果不初始化结构中的向量,它会自动为空还是具有随机内存位置的值?
- 如何在 3x4 数组中随机 4 个不同的位置
- SDL_Mixer再次播放时,从随机位置开始一段时间,然后从头开始
- 在长字符串(随机位置)中的C char搜索
- 动态分配存储数据在堆中的随机位置中
- C 2D char阵列有时会在随机位置复制数据
- Qt:交换QGraphicsRectItem位置的最佳方法是什么
- 在圆内的框外的随机位置
- 如何在c++中从txt文件的随机位置读取数据
- 如何在随机位置用特定数量的 1 和 0 填充数组?
- 用于随机访问和元素循环的最佳数据结构(C++)
- 最佳的c++方式来随机选择设置位在位集中的位置
- 初始化随机生成器的最佳位置
- 在皮条类中初始化默认值的最佳位置
- 记录C++代码的最佳位置
- 这个功能的最佳位置在哪里?c++
- 放置 #ifdef __cplusplus 外置"C"的最佳位置在哪里{#endif
- 调用MiniDumpWriteDump()以捕获崩溃的最佳位置
- MFC:处理上下文菜单消息的最佳位置