2017-10-04 11 views
0

次のコードでは、test_func_1はtest_func_2より約1桁遅いです。この操作のパフォーマンスを向上させる、または一致させることは不可能ですか?numbaベクトル化はnumpyよりも3d配列が遅いですか?

from numba import guvectorize 
import numpy as np 

@guvectorize(['void(float64[:,:,:], float64[:], float64[:,:,:])'], '(n,o,p),(n)->(n,o,p)', nopython=True) 
def test_func_1(time_series, areas, res): 
    for i in range(areas.size): 
     area = areas[i] 
     adjusted_area = (area/10000.) ** .12 # used to adjust erosion 
     for k in range(time_series.shape[0]): 
      res[i, 0, k] = time_series[i, 0, k] * area 
      res[i, 1, k] = time_series[i, 1, k] * adjusted_area 
      res[i, 2, k] = time_series[i, 2, k] * area 
      res[i, 3, k] = time_series[i, 3, k] * adjusted_area 


def test_func_2(time_series, areas): 
    array = np.swapaxes(time_series, 0, 2) 
    array[:, :2] *= areas 
    array[:, 2:] *= (areas/10000.) ** .12 
    return array 

dummy = np.float32(np.random.randint(0, 10, (20, 5, 5000))) 
areas = np.float32(np.random.randint(0, 10, 20)) 

test_func_1(dummy, areas) 
test_func_2(dummy, areas) 
+0

私は、与えられたデータセットで 'test_func_2(dummy、areas)'のために約80 u-secになります。それは本当にあなたのボトルネックですか?またはnumbaを学ぼうとしていますか?または、実際にはより大きなデータを扱っていますか? – Divakar

+0

私は 'test_func_1'が約2倍遅くなっています。時間を計るときは、ただちに(ジットのコンパイル時間を含む)時間を計っているのですか、それともコンパイルをキャッシュした後続の呼び出しをタイミングしていて、関数の実行時間になりますか? – JoshAdel

+0

簡潔にするために簡略化してあります。私は、非常に大きな3Dアレイ上で最終的に何万回も呼び出される同様の機能を使用するつもりです。 – triphook

答えて

3

@JoshAdelはコメントで述べたように、ここでの重要な違いは、numpyのは、その場でオリジナルを変更している間、あなたのnumbaバージョンは、新しい配列を割り当て、充填されていることです。

numpyに適切な.copy()を追加すると、少し遅くなります。また、あなたのnumbaバージョンは、gufuncでは不可能であると分かっていますが、gufuncが提供する放送を必要としない場合は、通常のjit関数で動作します。

def test_func_2(time_series, areas): 
    array = np.swapaxes(time_series, 0, 2).copy() 
    array[:, :2] *= areas 
    array[:, 2:] *= (areas/10000.) ** .12 
    return array 

dummy = np.float32(np.random.randint(0, 10, (20, 5, 5000))) 
areas = np.float32(np.random.randint(0, 10, 20)) 

%timeit test_func_1(dummy, areas) 
1.21 ms ± 5.33 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 

%timeit test_func_2(dummy, areas) 
1.77 ms ± 15.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 
関連する問題