我想在C ++中生成伪随机数,两个可能的选项是C ++ 11和Boost对应的特性。它们的使用方式基本相同,但我测试中的原生大约慢了4倍。
这是由于库中的设计选择,还是我错过了某种方法在某处禁用调试代码?
更新:代码在此处https://github.com/vbeffara/Simulations/blob/master/tests/test_prng.cpp,如下所示:
cerr << "boost::bernoulli_distribution ... \ttime = ";
s=0; t=time();
boost::bernoulli_distribution<> dist(.5);
boost::mt19937 boostengine;
for (int i=0; i<n; ++i) s += dist(boostengine);
cerr << time()-t << ", \tsum = " << s << endl;
cerr << "C++11 style ... \ttime = ";
s=0; t=time();
std::bernoulli_distribution dist2(.5);
std::mt19937_64 engine;
for (int i=0; i<n; ++i) s += dist2(engine);
cerr << time()-t << ", \tsum = " << s << endl;
(使用std::mt19937
代替std::mt19937_64
会使我的系统更慢。)
答案 0 :(得分:8)
That’s非常可怕。
我们来看看:
升压:: bernoulli_distribution&LT;&GT;
if(_p == RealType(0))
return false;
else
return RealType(eng()-(eng.min)()) <= _p * RealType((eng.max)()-(eng.min)());
的std :: bernoulli_distribution
__detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng);
if ((__aurng() - __aurng.min()) < __p.p() * (__aurng.max() - __aurng.min()))
return true;
return false;
两个版本都会调用引擎并检查输出是否位于与给定概率成比例的值范围的一部分。
最大的区别是,gcc版本调用辅助类_Adaptor
的函数。
此类“min
和max
函数分别返回0
和1
,operator()
然后使用给定的URNG调用std::generate_canonical
0
和1
之间的值。
std::generate_canonical
是一个带有循环的20行函数 - 在这种情况下它永远不会迭代多次,但它增加了复杂性。
除此之外,boost仅在分发的构造函数中使用param_type
,但随后将_p
保存为double
成员,而gcc拥有param_type
成员并且必须“获得”它的价值。
这一切都汇集在一起,编译器fails in optimizing。 Clang chokes even more就可以了。
如果您hammer hard enough,您甚至可以获得gcc的std::mt19937
和boost::mt19937
。
测试libc ++也不错,也许我稍后会添加它。
测试版本:增强1.55.0,gcc 4.8.2的libstdc ++头文件 请求的行号^^