python優化迴圈 python中的雙迴圈優化

2021-10-22 12:06:48 字數 3449 閱讀 7311

我正在嘗試優化以下迴圈:def numpy(nx, nz, c, rho):

for ix in range(2, nx-3):

for iz in range(2, nz-3):

a[ix, iz] = sum(c*rho[ix-1:ix+3, iz])

b[ix, iz] = sum(c*rho[ix-2:ix+2, iz])

return a, b

我嘗試了不同的解決方案,發現使用numba計算產品總和可以獲得更好的效能:

^$這導致time numpy : 4.1595

time numba1 : 0.6993

time numba2 : 1.0135

使用numba版本的sum函式(sum\u opt)效能非常好。但是我想知道為什麼numba版本的雙迴圈函式(numba2)會導致執行速度變慢。我試圖使用jit而不是autojit,指定引數型別,但情況更糟。在

我還注意到,先在最小的迴圈上迴圈比先在最大的迴圈上迴圈慢。有什麼解釋嗎?在

不管怎樣,我確信這個雙迴圈函式可以改進很多向量化問題(比如this)或使用其他方法(map?)但我對這些方法有點困惑。在

在我**的其他部分,我使用numba和numpy切片方法來替換所有顯式迴圈,但是在這個特殊的例子中,我不知道如何設定它。在

有什麼想法嗎?在

編輯import numpy as np

from scipy import signal

import time

@nb.jit(['float64(float64[:], float64[:])'], nopython=true)

def sum_opt(arr1, arr2):

s = arr1[0]*arr2[0]

for i in xrange(1, len(arr1)):

s+=arr1[i]*arr2[i]

return s

@nb.autojit

def numba1(nx, nz, c, rho, a, b):

for ix in range(2, nx-3):

for iz in range(2, nz-3):

a[ix, iz] = sum_opt(c, rho[ix-1:ix+3, iz])

b[ix, iz] = sum_opt(c, rho[ix-2:ix+2, iz])

return a, b

@nb.jit(nopython=true)

def numba2(nx, nz, c, rho, a, b):

for ix in range(2, nx-3):

for iz in range(2, nz-3):

a[ix, iz] = sum_opt(c, rho[ix-1:ix+3, iz])

b[ix, iz] = sum_opt(c, rho[ix-2:ix+2, iz])

return a, b

@nb.jit(['float64[:,:](int16, int16, float64[:], float64[:,:], float64[:,:])'], nopython=true)

def numba3a(nx, nz, c, rho, a):

for ix in range(2, nx-3):

for iz in range(2, nz-3):

a[ix, iz] = sum_opt(c, rho[ix-1:ix+3, iz])

return a

@nb.jit(['float64[:,:](int16, int16, float64[:], float64[:,:], float64[:,:])'], nopython=true)

def numba3b(nx, nz, c, rho, b):

for ix in range(2, nx-3):

for iz in range(2, nz-3):

b[ix, iz] = sum_opt(c, rho[ix-2:ix+2, iz])

return b

def convol(nx, nz, c, aa, bb):

s1 = rho[1:nx-1,2:nz-3]

s2 = rho[0:nx-2,2:nz-3]

kernel = c[:,none][::-1]

aa[2:nx-3,2:nz-3] = signal.convolve2d(s1, kernel, boundary='symm', mode='valid')

bb[2:nx-3,2:nz-3] = signal.convolve2d(s2, kernel, boundary='symm', mode='valid')

return aa, bb

nx = 1024

nz = 256

rho = np.random.rand(nx, nz)

c = np.random.rand(4)

a = np.zeros((nx, nz))

b = np.zeros((nx, nz))

ti = time.clock()

for i in range(1000):

a, b = numba1(nx, nz, c, rho, a, b)

print 'time numba1 : ' + `round(time.clock() - ti, 4)`

ti = time.clock()

for i in range(1000):

a, b = numba2(nx, nz, c, rho, a, b)

print 'time numba2 : ' + `round(time.clock() - ti, 4)`

ti = time.clock()

for i in range(1000):

a = numba3a(nx, nz, c, rho, a)

b = numba3b(nx, nz, c, rho, b)

print 'time numba3 : ' + `round(time.clock() - ti, 4)`

ti = time.clock()

for i in range(1000):

a, b = convol(nx, nz, c, a, b)

print 'time convol : ' + `round(time.clock() - ti, 4)`

您的解決方案非常優雅,但我必須在**中大量使用此函式。因此,對於1000次迭代,這將導致time numba1 : 3.2487

time numba2 : 3.7012

time numba3 : 3.2088

time convol : 22.7696

autojit和{}非常接近。

但是,在使用jit時,指定所有引數型別似乎很重要。在

當函式有多個輸出時,我不知道是否有方法在jit修飾符中指定引數型別。有人嗎?在

現在我沒有找到其他的解決辦法,除了使用numba。歡迎有新想法!在

python優化迴圈 Python 優化迴圈

我希望優化一些由兩個巢狀迴圈組成的 python 我對numpy並不那麼熟悉,但據我所知,它應該能夠幫助我提高這項任務的效率.下面是我編寫的測試 它反映了實際 中發生的情況.目前使用numpy範圍和迭代器比通常的python更慢.我究竟做錯了什麼?這個問題的最佳解決方案是什麼?謝謝你的幫助!impo...

Python之迴圈優化

儘量減少迴圈內部不必要的計算 巢狀迴圈中,儘量減少內層迴圈的計算,盡可能向外提。區域性變數查詢較快,盡量使用區域性變數 import time start time.time for i in range 10000 lib1 for x in range 10000 1000 x 1000 end...

python效率怎麼樣 如何優化python的效率

優化python的效率的方法 1 優化演算法時間複雜度 2 減少冗餘資料 3 合理使用copy與deepcopy 4 使用dict或set查詢元素 5 合理使用生成器 generator 和yield。優化方法 1 優化演算法時間複雜度 演算法的時間複雜度對程式的執行效率影響最大,在python中可...