1
我正在爲一個複雜的水庫運行問題開發優化代碼。其中一部分要求我計算大量潛在解決方案的目標函數。我正在測試Rosenbrock函數的優化器並試圖提高速度。我注意到,當我剖析代碼時,在for循環中計算目標函數是代碼瓶頸之一,因此我開發了一種爲多組決策變量並行執行此操作的方法。我有兩個目標函數計算器:一組決策變量的FO和多組決策變量的P_FO。目標函數的計算是我的代碼中最慢的部分之一,所以我想用@jit進一步加快速度。我使用@jit測試了這兩個函數,發現使用@jit的P_FO函數比使用它更慢。代碼如下:@jit減速功能
import time
import numpy as np
from numba import jit
def FO(X):
#Rosenbrock function
ObjV=0
for i in range(65-1):
F=100*((X[i+1]-X[i]**2)+(X[i]-1)**2)
ObjV+=F
return ObjV
t0=time.time()
X=10+np.zeros(65)
for i in range(5000):
FO(X)
t1 = time.time()
total = t1-t0
print("time FO="+str(total))
@jit
def FO(X):
#Rosenbrock function
ObjV=0
for i in range(65-1):
F=100*((X[i+1]-X[i]**2)+(X[i]-1)**2)
ObjV+=F
return ObjV
t0=time.time()
X=10+np.zeros(65)
for i in range(5000):
FO(X)
t1 = time.time()
total = t1-t0
print("time FO with @jit="+str(total))
def P_FO(X):
ObjV=np.zeros(X.shape[0])
for i in range(X.shape[1]-1):
F=100*((X[:,i+1]-X[:,i]**2)+(X[:,i]-1)**2)
ObjV+=F
return ObjV
t0=time.time()
X=10+np.zeros((65, 5000))
P_FO(X)
t1 = time.time()
total = t1-t0
print("time P_FO="+str(total))
@jit
def P_FO(X):
ObjV=np.zeros(X.shape[0])
for i in range(X.shape[1]-1):
F=100*((X[:,i+1]-X[:,i]**2)+(X[:,i]-1)**2)
ObjV+=F
return ObjV
t0=time.time()
X=10+np.zeros((65, 5000))
P_FO(X)
t1 = time.time()
total = t1-t0
print("time P_FO with @jit="+str(total))
結果:
time FO=0.523999929428
time FO with @jit=0.0720000267029
time P_FO=0.0380001068115
time P_FO with @jit=0.229000091553
任何人都可以指向我一個理由@jit減慢並行目標函數P_FO?是因爲使用了np.zeros還是array.shape()?
這很有道理。由於我將每次模擬運行300次(以及數百萬次模擬),它可能仍會改善結果。 – Kingle
只是好奇 - 如果@jit函數在另一個.py文件中,它是否每次調用它時都要編譯?或者從我的主函數編譯一次,加速其餘函數調用? – Kingle
不,一旦導入,編譯只需要完成一次。更好的是,有一個'cache = True'選項可以緩存python會話中的編譯。請參閱http://numba.pydata.org/numba-doc/latest/user/jit.html#cache上的文檔 – chrisb