c ++ 11 STL的binomial_distribution非常慢

时间:2012-10-31 17:15:18

标签: c++ gcc random c++11 libstdc++

我使用STL'随机'生成二元分布的随机数。当范围很大时,它变得非常慢。对于范围40,生成100个数字需要12秒。对于更大的范围,时间会急剧增加(我需要大约10000的范围)。它似乎不依赖于概率参数。我使用的是g ++ 4.5.0。

#include <iostream>
#include <random>

using namespace std;

vector<int> v;

default_random_engine gen(123);
binomial_distribution<int> rbin(40,0.7);

int main(){
  v.reserve(2000);
  for(int i=0; i<100;++i){
    v.push_back(rbin(gen));
   }
}

输出:

50.~/.../fs/> g++ -std=c++0x q.cpp 
51.~/.../fs/> time ./a.out 
real    0m12.102s
user    0m12.094s
sys     0m0.002s
52.~/.../fs/>

我可以使用法线近似,但它对于概率参数的极值是不好的。

更新

使用&#39; -O3&#39;选项时间变为~2秒。使用g ++ 4.6.3时,问题完全消失了 - 几乎没有时间依赖于范围,100个数字的生成需要5ms。

2 个答案:

答案 0 :(得分:7)

对于大范围,libstdc ++将使用有效的拒绝算法(在Devroye之后,L。非均匀随机变量生成),但仅当C99 TR1数学可用时(_GLIBCXX_USE_C99_MATH_TR1) 。否则,它将回退到一个简单的等待时间方法,它将在该范围内具有线性性能。

我建议检查_GLIBCXX_USE_C99_MATH_TR1的值以及性能是否会在更新版本的g ++中得到改善。

答案 1 :(得分:1)

当性能很重要时,您应确保启用优化。

此外,您应该查看可用的随机数引擎,并确保您使用符合性能/尺寸/质量要求的引擎。

如果问题确实是std::binomial_distribution::operator()没有充分执行,则可能必须使用不同的标准库实现,或std::binomial_distribution的替代实现。 boost应该有<random>的替代实现,你可以使用它而不会有太多麻烦,libc ++也有一个替代实现,但它将更难以使用,因为你必须替换整个标准库实施