所有代码都在linux上的同一台机器上运行。
在python中:
import numpy as np
drr = abs(np.random.randn(100000,50))
%timeit np.log2(drr)
10个循环,最佳3:每循环77.9 ms
在C ++中(使用g ++ -o log ./log.cpp -std = c ++ 11 -O3编译):
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
#include <ctime>
int main()
{
std::mt19937 e2(0);
std::normal_distribution<> dist(0, 1);
const int n_seq = 100000;
const int l_seq = 50;
static double x[n_seq][l_seq];
for (int n = 0;n < n_seq; ++n) {
for (int k = 0; k < l_seq; ++k) {
x[n][k] = abs(dist(e2));
if(x[n][k] <= 0)
x[n][k] = 0.1;
}
}
clock_t begin = clock();
for (int n = 0; n < n_seq; ++n) {
for (int k = 0; k < l_seq; ++k) {
x[n][k] = std::log2(x[n][k]);
}
}
clock_t end = clock();
在60毫秒内运行
在MATLAB中:
abr = abs(randn(100000,50));
tic;abr=log2(abr);toc
经过的时间是7.8毫秒。
我可以理解C ++和numpy之间的速度差异,但MATLAB击败了一切。 我遇到过 http://fastapprox.googlecode.com/svn/trunk/fastapprox/src/fastonebigheader.h 但这只会浮动,而不是双倍,我不知道如何将其转换为加倍。
我也试过这个: http://hackage.haskell.org/package/approximate-0.2.2.1/src/cbits/fast.c 它具有快速的日志功能,当编译为numpy ufunc时,运行时间为20毫秒,这很好,但精度损失很大。
关于如何实现MATLAB获得的神奇log2速度的任何想法?
更新
谢谢大家的评论,这非常快,非常有帮助!实际上,答案是并行化,即将负载分散在多个线程上。按照@morningsun的建议,
%timeit numexpr.evaluate('log(drr)')
给出5.6 ms,与MATLAB相同,谢谢! numexpr启用了MKL