我正在为一个复杂的水库操作问题开发一个优化代码。这需要我计算大量潜在解决方案的目标函数。我正在测试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()?
发布于 2017-07-21 18:40:42
numba函数是延迟编译的,也就是说,直到第一次调用时才进行编译,所以您的计时是在捕获一次性编译开销。如果我在运行计时节之前调用每个函数一次,我会得到:
time FO=0.4103426933288574
time FO with @jit=0.0020008087158203125
time P_FO=0.04154801368713379
time P_FO with @jit=0.004002809524536133
https://stackoverflow.com/questions/45226006
复制相似问题