创建uniform_int_distribution<int> 对象是否昂贵?

时间:2021-02-09 15:53:38

标签: c++ random uniform-distribution

我正在编写代码,其中随机数是从均匀分布中采样的,对于 for 循环中的某些迭代,其边界会有所不同,例如,

std::mt19937 generator{0};
for(int i = 0; i < n; ++i)
{
  if(conditions are met)
  {
    // low and hi bounds change for each iteration
    std::uniform_int_distribution<int> U(low, hi);
    auto sample = U(generator);
  }

}

这是我目前编写代码的方式,但它会为满足条件的每次迭代创建和删除一个临时 std::uniform_int_distribution<int> 对象。这是一个昂贵的过程吗?编译器优化能否在 for 循环之外构造对象,并在 if 语句中重建均匀分布的边界?我不确定这是否一定会更快。

还有其他更好的方法吗?

1 个答案:

答案 0 :(得分:1)

std::uniform_int_distribution 创建起来通常成本不高,并且只包含最小/最大值对作为其成员。至少 stdlibc++libc++VC++ 是这种情况。一个好的优化编译器应该能够完全消除它的任何痕迹。

然而,这并不能保证,此外,允许分发是有状态的。尽管 normal_distribution 的情况更常见,而不是 uniform_int_distribution


从技术上讲,可以重复使用分布并在循环中重新初始化它的参数:

std::mt19937 generator{ 0 };
std::uniform_int_distribution<int> U;
for (int i = 0; i < n; ++i)
{
    // low and hi bounds change for each iteration
    U.param(std::uniform_int_distribution<int>::param_type(low, hi));
    auto sample = U(generator);
}

生成的代码可能是相同的(或者稍微更糟 - 检查以确保),并且它不能解决 normal_distribution 的问题,因为更改参数会重置状态。