在我的程序中,我使用随机数生成器。我认为一般规则是你应该将事物定义为接近它们被“调用”的地方,但这对于随机数生成器是否也适用?
例如,在我的代码中,我可以选择:
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);
}
我想说第一种方法更快,但由于阅读了很多线程,我觉得它总是把所有东西放在靠近它所调用的地方。我有点困惑。
答案 0 :(得分:5)
在这种情况下,在你的循环之外创建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的正确使用模型。
答案 1 :(得分:3)
原因是,当您在代码顶部找到随机生成器定义时,它们将变为全局,并且在您第一次点击“运行”按钮时将自动定义它们。如果您在多个地方使用这些变量,那么这可能是最好的主意。但如果你不是,你就不需要它了。因为在某些情况下,他们甚至可能不会打电话。无论如何,这个建议是用于类或方法的用法。
但是,从我看到的情况来看,您将在for循环中使用该数字,这将导致您的计算机在代码下运行1000次。
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(-2147483647, 2147483646);
这是不必要的,也没用。我相信你的第一个代码在性能方面会更好。