【发布时间】:2016-06-25 05:03:30
【问题描述】:
我试图了解如何使用 C++11 随机数生成功能。我关心的是性能。
假设我们需要在0..k之间生成一系列随机整数,但k每一步都在变化。最好的方法是什么?
例子:
for (int i=0; i < n; ++i) {
int k = i; // of course this is more complicated in practice
std::uniform_int_distribution<> dist(0, k);
int random_number = dist(engine);
// do something with random number
}
<random> 标头提供的分布非常方便。但它们对用户来说是不透明的,所以我无法轻易预测它们的性能。例如,上面的dist 的构造会导致多少(如果有)运行时开销并不清楚。
相反,我可以使用类似的东西
std::uniform_real_distribution<> dist(0.0, 1.0);
for (int i=0; i < n; ++i) {
int k = i; // of course this is more complicated in practice
int random_number = std::floor( (k+1)*dist(engine) );
// do something with random number
}
避免在每次迭代中构造一个新对象。
随机数通常用于性能很重要的数值模拟中。在这些情况下使用<random> 的最佳方式是什么?
请不要回答“profile it”。分析是有效优化的一部分,但对如何使用库以及该库的性能特征有很好的理解也是如此。如果答案是它取决于标准库的实现,或者知道的唯一方法是分析它,那么我宁愿根本不使用来自<random> 的分布。相反,我可以使用我自己的实现,这对我来说是透明的,并且在必要时更容易优化。
【问题讨论】:
-
另一个考虑因素:像
std::mt19937这样的生成器的优点之一是它们是可移植的,并且实现是标准强制。使用带有给定种子的生成器必须在任何符合要求的实现上产生相同的随机序列uint32_t。但是,分发适配器std::uniform_int_distribution没有此保证,因此如果您使用它们,如果您更改编译器或其他东西,您可能会从同一个种子中获得不同的整数序列。这可能是数值模拟的考虑因素。 -
@ChrisBeck 我不知道,谢谢指出!
标签: c++ performance c++11 random