2015-11-22 22 views
3

我正在嘗試使用numba做一些計時比較。使用numba的Python代碼計時

我沒有在以下mwe.py明白的是爲什麼我得到不同的結果

from __future__ import print_function 
import numpy as np 
from numba import autojit 
import time 


def timethis(method): 
    '''decorator for timing function calls''' 
    def timed(*args, **kwargs): 
     ts = time.time() 
     result = method(*args, **kwargs) 
     te = time.time() 
     print('{!r} {:f} s'.format(method.__name__, te - ts)) 
     return result 
    return timed 


def pairwise_pure(x): 
    '''sample function, compute pairwise distancee, see: jakevdp.github.io/blog/2013/06/15/numba-vs-cython-take-2/''' 
    M, N = x.shape 
    D = np.empty((M, M), dtype=np.float) 
    for i in range(M): 
     for j in range(M): 
      d = 0. 
      for k in range(N): 
       tmp = x[i, k] - x[j, k] 
       d += tmp * tmp 
      D[i, j] = np.sqrt(d) 
    return D 

# first version 
@timethis 
@autojit 
def pairwise_numba(args): 
    return pairwise_pure(args) 

# second version 
@timethis 
def pairwise_numba_alt(args): 
    return autojit(pairwise_pure)(args) 

x = np.random.random((1e3, 10)) 

pairwise_numba(x) 
pairwise_numba_alt(x) 

評估python3 mwe.py得到下面的輸出:

'pairwise_numba' 5.971631 s 
'pairwise_numba_alt' 0.191500 s 

在第一個版本,我裝點使用方法timethis來計算時間,用autojit加快代碼的速度,然後在第二個函數中用timethis裝飾函數,之後調用autojit(...)。

有人有解釋嗎?

+0

我不知道numba,但從裝飾者的角度來看這兩個例子並不相同,在第一次你有timethis(autojit(pairwise_numba)),而在第二次這樣(pairwise_numba_alt) –

+2

它看起來像在第一個版本,你只是自動調整包裝。也許它會委託給它實際上很快包裝的功能,但它所包裝的功能不會發生抖動。 – user2357112

+0

@ user2357112,是的,我認爲你有正確的分析,在第一個版本中,它看起來像autojit以某種方式應用於包裝器而不是內部函數,因此不會導致優化。 – neok

回答

2

實際上documentation明確規定,爲了優化,對裝飾函數「內部」的其他函數的每個調用都應該進行裝飾,否則它不會被優化。

對於許多函數,如numpy函數是不必要的,因爲它們是高度優化的,但對於本機python函數是這樣的。