簡體   English   中英

為什么numpy的exp比Matlab慢?如何讓它更快?

[英]Why is numpy's exp slower than Matlab? How to make it faster?

我有一個非常簡單的例子,它表明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

為了提高性能,特別是在大型數據集上,我們可以利用numexpr模塊來實現這樣的超越功能 -

import numexpr as ne

b = ne.evaluate('exp(a)')

標桿

對於正確的基准測試,我會timeit on MATLABNumPy's %timeit 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-sectimeit

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM