每次循环进行临时均匀随机分布的效率如何

How efficient is it to make a temporary uniform random distribution each time round a loop?

本文关键字:分布 随机 效率 循环      更新时间:2023-10-16

例如:

for (...)
{
    ... std::uniform_real_distribution<float>(min, max)(rng) ...
}

直觉上在我看来,构造函数除了存储这两个值之外不需要做太多事情,并且 uniform_*_distribution 实例中不应该有任何状态。我自己还没有介绍过它(我还没有处于项目的那种阶段),但我觉得这个问题属于那里:)

我知道这对于某些分布类型来说是一个坏主意 - 例如,std::normal_distribution可能会成对生成其数字,并且每次都会浪费第二个数字。

我觉得我所拥有的比仅仅访问rng()和自己做数学更具可读性,但如果有任何其他方法可以更直接地编写它,我会很感兴趣。

std::uniform_real_distribution的对象是轻量级的,所以每次在循环中构造它们都不是问题。

有时,隐藏的内部分布状态很重要,但在这种情况下并非如此。 reset()函数在所有流行的 STL 实现中都不做任何事情:

void
reset() { }

例如,对于std::normal_distribution则不然:

void
reset()
{ _M_saved_available = false; }

嗯,一些 rng 具有实质性状态,例如 Mersenne twister 有大约 600 个单词的状态(尽管我不知道它的C++实现)。因此,有可能在循环中占用一些时间来重复创建 rng。

然而,很可能即使考虑到状态,它仍然足够快,花费额外的时间来构建 rng 并不重要。只有分析才能确定。

我个人的偏好是将rng移出循环,并在可能的情况下通过简单的公式计算所需的值(例如 min + (max - min)*x用于均匀分布或mu + sigma*x用于高斯分布)。