所有代码都在同一台Linux机器上运行。
使用Python:
import numpy as np
drr = abs(np.random.randn(100000,50))
%timeit np.log2(drr)
每轮运行10次,3轮取最佳结果:平均每轮耗时77.9毫秒。
在C++中(使用g++编译器,命令为"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 但这个只支持float类型,不支持double类型,而且我不确定如何将其转换为double类型。
我还尝试了这个: http://hackage.haskell.org/package/approximate-0.2.2.1/src/cbits/fast.c 它具有快速的log函数,并且编译为numpy ufunc时运行时间为20毫秒,这很好,但精度损失很大。
有什么想法可以达到MATLAB得到的神奇的log2速度吗?
更新
谢谢大家的评论,非常快速和有帮助!实际上,答案是并行化,即将负载分布在多个线程上。根据@morningsun的建议:
%timeit numexpr.evaluate('log(drr)')
得到5.6毫秒,与MATLAB相当,谢谢!numexpr是MKL启用的。
log2
,所以请使用log(a)/log(2.0)
。 - user2379410.data
属性轻松访问。 - ali_m