Python 为什么是numpy';s exp比Matlab慢?如何使它更快?
我有一个非常简单的例子,它显示NumPy的Python 为什么是numpy';s exp比Matlab慢?如何使它更快?,python,matlab,performance,numpy,Python,Matlab,Performance,Numpy,我有一个非常简单的例子,它显示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
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
为了提高性能,特别是在大型数据集上,我们可以利用这些超越函数-
import numexpr as ne
b = ne.evaluate('exp(a)')
标杆管理
对于适当的基准测试,我将使用-
设置#1
MATLAB:
>> a = rand([100*1000,1]);
>> func = @() exp(a);
>> timeit(func)
ans =
0.0013 % That's 1.3 m-sec
>> a = rand([1000*10000,1]);
>> func = @() exp(a);
>> timeit(func)
ans =
0.0977 % That's 97 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
MATLAB : 97 m-sec
NumPy : 154 m-sec
Numexpr : 36 m-sec
设置#2
MATLAB:
>> a = rand([100*1000,1]);
>> func = @() exp(a);
>> timeit(func)
ans =
0.0013 % That's 1.3 m-sec
>> a = rand([1000*10000,1]);
>> func = @() exp(a);
>> timeit(func)
ans =
0.0977 % That's 97 m-sec
努比:
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 : 1.3 m-sec
NumPy : 1.5 m-sec
Numexpr : 0.4 m-sec
MATLAB : 97 m-sec
NumPy : 154 m-sec
Numexpr : 36 m-sec
与
tic toc进行适当的基准测试
这个问题中的基准测试的缺点是,我们在一个循环中得到了toc经过的时间,而这个循环没有运行足够的时间来给我们提供任何准确的时间。普遍接受的想法是,toc
经过的计时必须至少接近1
sec标记
因此,通过这些校正,可以使用tic-toc
进行更精确的计时测试-
tic
for i=1:1000,
b = exp(a);
end
t=toc;
timing = t./1000
这就产生了-
timing =
0.0010
这与我们的
1.3 m-sec
和timeit
非常接近。这里更大的问题是,为什么您的跑步速度比OPsMy time结果快1000倍,这是所有exp(a)跑步的总时间,而不是平均时间@Divakar——我添加了numexpr,这很好,也很有帮助,但我们仍然比Matlab慢2倍多。@SlaterTyranus实际上%timeit
让我们平均运行1000次。OP是累积的,这不是平均值。不过,我不确定这是如何成为更大的问题的。“我们应该把重点放在加速上。”迪瓦卡哈,那就行了。降到3-4倍增量,这是一个更合理的硬件增量。@Isaaccher使用您信任的setup='import numpy作为np;导入num..
code,然后使用我在文章末尾发布的tic-toc代码。对于三个版本:MATLAB、NumPy、Numexpr,您得到了什么结果?你能在问题中加上这一点吗,或者在评论中告诉我?timeit文档说没有多行字符串文字。我在猜测,如果设置部分作为timeit运行的一部分进行评估,那么您传递设置部分的方式。通过在python中模仿matlab中的tic/tock设置,您可以进行直接的苹果对苹果的比较。@SlaterTyranus:docs说stmt
和setup
不能包含多行字符串文字,并不是说它们本身不能跨越多行。我相信这是因为它用来调整多行输入缩进的timeit
会破坏输入中的多行字符串文字。而且,就如何使其更快而言,这实际上与numpy无关,而与引擎盖下的lapack无关。如果你想改进它,那就是你要看的地方。是的,我把设置字符串改成了用分号分隔的单个字符串,同样的计时结果。@user2357112我的错误。在过去,我遇到了一些微妙的问题,无法从思想上解析输入字符串。