Умножения не занимают много времени в этом расчете. Но возведение в степень ((value)**(i+1))
очень дорого и, вероятно, не нужно. Также не ясно, используете ли вы глобальные переменные в вашей функции. Если так, избегайте этого.
Оригинальная реализация
@nb.njit(fastmath=True,error_model="numpy")
def trial_orig(part,value,Lmin,Lmax,Bn,leg):
kernel = 0.
for i in range(0,Lmax+1):
kernel += ((2*i+1)/part)*((value)**(i+1))*leg[i]*Bn[i]
return kernel
Как избежать возведения в степень
Обратите внимание, что умножение fact
на самого себя является алгебраически таким же, как непосредственное вычисление с возведением в степень. Поскольку это числовая математика, результаты могут немного отличаться.
@nb.njit(fastmath=True,error_model="numpy")
def trial_mod(part,value,Lmin,Lmax,Bn,leg):
#I assume that Lmin is always >0
assert Lmin>=0.
kernel = 0.
fact=value**(Lmin+1)
for i in range(Lmin,Lmax):
kernel += ((2*i+1)/part)*fact*leg[i]*Bn[i]
fact*=value
return kernel
Задержка
leg=np.random.rand(3001)
Bn=np.random.rand(3001)
Lmin=0
Lmax=3000
part=15.
value=0.8
%timeit trial_orig(part,value,Lmin,Lmax,Bn,leg)
100 µs ± 1.11 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit trial_mod(part,value,Lmin,Lmax,Bn,leg)
4.25 µs ± 21.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)