我有一个非常简单的例子,它表明NumPy的np.exp
比Matlab慢约10倍。我怎样才能加速Python?我正在运行32位Python 2.7,NumPy版本1.11.3,而numpy正在使用MKL blas& lapack库。
此外,时间的差异是如此之大,以至于我不认为计时机制会产生很大的影响。
Python中的代码示例:
import numpy as np
import timeit
setup='import numpy as np; import numexpr as ne; n=100*1000; a = np.random.uniform(size=n)'
time = timeit.timeit('b=np.exp(a)', setup=setup, number=1000)
print 'Time for 1000 (np.exp): ',time
time = timeit.timeit('b=ne.evaluate("exp(a)")', setup=setup, number=1000)
print 'Time for 1000 (numexpr): ',time
结果:
Time for 1000 (np.exp): 2.25906916167
Time for 1000 (numexpr): 0.591470532849
在Matlab中:
a = rand([100*1000,1]);
times = [];
for i=1:1000,
tic
b = exp(a);
t=toc;
times(i) = t;
end
fprintf('Time for 1000: %f\n',sum(times));
导致:
Time for 1000: 0.268527
答案 0 :(得分:4)
为了提高性能,特别是在大型数据集上,我们可以利用numexpr
module来实现这些超越函数 -
import numexpr as ne
b = ne.evaluate('exp(a)')
要进行正确的基准测试,我会使用timeit on MATLAB
和NumPy's %timeit
-
设置#1
MATLAB:
>> a = rand([100*1000,1]);
>> func = @() exp(a);
>> timeit(func)
ans =
0.0013 % That's 1.3 m-sec
NumPy在相同大小的数据集上:
In [417]: n=100*1000
...: a = np.random.uniform(size=n)
...:
In [418]: %timeit np.exp(a)
1000 loops, best of 3: 1.5 ms per loop
In [419]: %timeit ne.evaluate('exp(a)')
1000 loops, best of 3: 397 µs per loop
因此,
MATLAB : 1.3 m-sec
NumPy : 1.5 m-sec
Numexpr : 0.4 m-sec
设置#2
MATLAB:
>> a = rand([1000*10000,1]);
>> func = @() exp(a);
>> timeit(func)
ans =
0.0977 % That's 97 m-sec
NumPy:
In [412]: n=1000*10000
...: a = np.random.uniform(size=n)
...:
In [413]: %timeit np.exp(a)
10 loops, best of 3: 154 ms per loop
In [414]: %timeit ne.evaluate('exp(a)')
10 loops, best of 3: 36.5 ms per loop
因此,
MATLAB : 97 m-sec
NumPy : 154 m-sec
Numexpr : 36 m-sec
使用tic-toc
问题中的基准测试的错误是我们在一个循环内获得了toc经过的时间,这个循环没有运行足够的时间来给我们任何准确的时间。普遍接受的想法是toc
经过的时间必须至少接近1
秒标记。
因此,通过这些更正,使用tic-toc
进行更准确的时序测试将是 -
tic
for i=1:1000,
b = exp(a);
end
t=toc;
timing = t./1000
这会产生 -
timing =
0.0010
这与我们的1.3 m-sec
timeit
接近。