对于类蒙特卡罗模拟,我需要随机选取数千个随机高斯向量(即具有独立正态分布条目的向量)。每个这样的矢量都是固定长度(大约100)。
NumPy有一种实现这个目标的方法:
import numpy.random
vectors = [numpy.random.normal(size=100) for _ in xrange(10000)]
NumPy的random.normal
函数具有线性复杂性,具有小尺寸值的开销。然而,看起来size=100
的开销并不重要(可能约为30%,经验测试;与size=1
的开销相比,约为2300%)。也许我可以通过滚动一次来节省一些开销,然后分割数组(尚未尝试过)。
然而,对于我的需求,它仍然太多太慢了。也许我在这里太贪心了;我知道NumPy的随机函数是用c
编写的,并考虑了优化;仍然,
timeit numpy.random.normal(size=100)
# 100000 loops, best of 3: 5.8 us per loop
(在IPython中测试,使用其魔法%timeit
)
对于10k向量,这使得~0.06秒。我想知道是否有一个更快的方法,这将允许我在不到0.6毫秒内滚动大小为100的10k向量(比如说),快100倍。解决方案可能涉及c
扩展或任何需要。
基于来自c++
的{{3}}的非常简单的cppreference
代码显示了更好的效果:
#include <iostream>
#include <random>
int main()
{
float x;
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution <> d(0,1);
for(int i=0; i < 100000; i++)
{
x = d(gen);
}
std::cout << x << '\n';
return 0;
}
和时间显示:
real 0m0.028s
user 0m0.020s
sys 0m0.004s
比NumPy提供的速度快约20倍。但是,我不确定python的c扩展的开销,我没有直觉知道这是否可以成为比numpy.random.normal
更快的python函数。