I thought this community is better place to ask my question so I ask here rather than at StackOverflow.
Recently, I learned that Numba
can make Python function which uses numpy
modules and for
loops super faster so I was trying to implement it to my code in order to optimize execution time. However, ironically, using it made the code execution time much slower. Following codes show the comparison between 1) code using Numba and 2) original code.
Also, I use 2 data as an input (numpy.ndarray
) with names n
and e
which are both float32
arrays of length 201. You can test my code with these data.
n=np.array([0.00000000e+00, -2.90246233e-02, -2.24490568e-01,
-7.16749728e-01, -1.57171035e+00, -2.77444601e+00,
-4.22764540e+00, -5.76536274e+00, -7.17996216e+00,
-8.25780201e+00, -9.09192276e+00, -9.90472031e+00,
-1.06955252e+01, -1.14638758e+01, -1.22095718e+01,
-1.29326763e+01, -1.36334448e+01, -1.43122253e+01,
-1.49694138e+01, -1.56054220e+01, -1.62206211e+01,
-1.68152523e+01, -1.73894081e+01, -1.79430256e+01,
-1.84757977e+01, -1.89870377e+01, -1.94757748e+01,
-1.99407864e+01, -2.03805809e+01, -2.07932720e+01,
-2.11767120e+01, -2.15285759e+01, -2.18464222e+01,
-2.21277046e+01, -2.23698120e+01, -2.25701656e+01,
-2.27262192e+01, -2.28354397e+01, -2.28954563e+01,
-2.29041901e+01, -2.28599644e+01, -2.27614594e+01,
-2.26076698e+01, -2.23979702e+01, -2.21322174e+01,
-2.18107166e+01, -2.14341793e+01, -2.10038280e+01,
-2.05215683e+01, -1.99899464e+01, -1.94121590e+01,
-1.87920952e+01, -1.81344280e+01, -1.74445496e+01,
-1.67284374e+01, -1.59926023e+01, -1.52440386e+01,
-1.44902058e+01, -1.37389374e+01, -1.29982576e+01,
-1.22761898e+01, -1.15806122e+01, -1.09191751e+01,
-1.02992201e+01, -9.72764969e+00, -9.21087074e+00,
-8.75471401e+00, -8.36433029e+00, -8.04401970e+00,
-7.79723310e+00, -7.62662983e+00, -7.53405952e+00,
-7.52038527e+00, -7.58545780e+00, -7.72822046e+00,
-7.94686508e+00, -8.23878956e+00, -8.60053539e+00,
-9.02776337e+00, -9.51539421e+00, -1.00577345e+01,
-1.06485300e+01, -1.12809696e+01, -1.19478493e+01,
-1.26417017e+01, -1.33548985e+01, -1.40797272e+01,
-1.48085299e+01, -1.55338354e+01, -1.62484665e+01,
-1.69456844e+01, -1.76192360e+01, -1.82633667e+01,
-1.88728962e+01, -1.94433289e+01, -1.99709244e+01,
-2.04526272e+01, -2.08860626e+01, -2.12695827e+01,
-2.16023121e+01, -2.18841362e+01, -2.21156521e+01,
-2.22980556e+01, -2.24331856e+01, -2.25235310e+01,
-2.25722427e+01, -2.25830765e+01, -2.25602932e+01,
-2.25085907e+01, -2.24330215e+01, -2.23388729e+01,
-2.22315712e+01, -2.21166210e+01, -2.19994831e+01,
-2.18853989e+01, -2.17793064e+01, -2.16857681e+01,
-2.16088982e+01, -2.15522213e+01, -2.15185966e+01,
-2.15101852e+01, -2.15284405e+01, -2.15740509e+01,
-2.16469669e+01, -2.17463741e+01, -2.18707085e+01,
-2.20176525e+01, -2.21841602e+01, -2.23664932e+01,
-2.25603275e+01, -2.27608757e+01, -2.29629631e+01,
-2.31610470e+01, -2.33492279e+01, -2.35214043e+01,
-2.36715298e+01, -2.37937660e+01, -2.38824825e+01,
-2.39323406e+01, -2.39385643e+01, -2.38971081e+01,
-2.38046494e+01, -2.36585808e+01, -2.34572048e+01,
-2.31998024e+01, -2.28866425e+01, -2.25189037e+01,
-2.20986404e+01, -2.16287670e+01, -2.11129856e+01,
-2.05556641e+01, -1.99617062e+01, -1.93365269e+01,
-1.86859131e+01, -1.80159054e+01, -1.73325996e+01,
-1.66420517e+01, -1.59501858e+01, -1.52626762e+01,
-1.45847788e+01, -1.39213161e+01, -1.32765999e+01,
-1.26543894e+01, -1.20577383e+01, -1.14889488e+01,
-1.09496098e+01, -1.04407034e+01, -9.96269608e+00,
-9.51548195e+00, -9.09836483e+00, -8.71012592e+00,
-8.34911537e+00, -8.01335907e+00, -7.70055103e+00,
-7.40815973e+00, -7.13349152e+00, -6.87368536e+00,
-6.62575817e+00, -6.38672686e+00, -6.15366173e+00,
-5.92375469e+00, -5.69433641e+00, -5.46290398e+00,
-5.22722960e+00, -4.98536777e+00, -4.73564768e+00,
-4.47674179e+00, -4.20764303e+00, -3.92769504e+00,
-3.63661599e+00, -3.33451986e+00, -3.02191830e+00,
-2.61823845e+00, -2.09174943e+00, -1.52332258e+00,
-9.90778685e-01, -5.54975927e-01, -2.49610826e-01,
-7.68868327e-02, -9.74494778e-03, 0.00000000e+00], dtype=float32)
e=np.array([0.00000000e+00, -2.39476264e-02, -1.95374981e-01,
-6.55762613e-01, -1.50696099e+00, -2.77968431e+00,
-4.41394567e+00, -6.25681400e+00, -8.07964897e+00,
-9.61341381e+00, -1.09259253e+01, -1.22610502e+01,
-1.36115866e+01, -1.49705763e+01, -1.63314114e+01,
-1.76879139e+01, -1.90344372e+01, -2.03657932e+01,
-2.16773891e+01, -2.29651966e+01, -2.42257977e+01,
-2.54562702e+01, -2.66542950e+01, -2.78181095e+01,
-2.89464245e+01, -3.00384007e+01, -3.10936413e+01,
-3.21121521e+01, -3.30942726e+01, -3.40405350e+01,
-3.49516640e+01, -3.58286057e+01, -3.66724052e+01,
-3.74841537e+01, -3.82649269e+01, -3.90158615e+01,
-3.97381325e+01, -4.04328537e+01, -4.11011162e+01,
-4.17439575e+01, -4.23624077e+01, -4.29573746e+01,
-4.35296898e+01, -4.40801773e+01, -4.46096611e+01,
-4.51190338e+01, -4.56091652e+01, -4.60809402e+01,
-4.65354042e+01, -4.69738083e+01, -4.73974800e+01,
-4.78078232e+01, -4.82064171e+01, -4.85949020e+01,
-4.89749336e+01, -4.93481598e+01, -4.97163124e+01,
-5.00811615e+01, -5.04445229e+01, -5.08082886e+01,
-5.11744041e+01, -5.15448380e+01, -5.19215736e+01,
-5.23065796e+01, -5.27017555e+01, -5.31089096e+01,
-5.35298271e+01, -5.39661331e+01, -5.44192924e+01,
-5.48905334e+01, -5.53807945e+01, -5.58906784e+01,
-5.64204826e+01, -5.69702682e+01, -5.75397987e+01,
-5.81285400e+01, -5.87356644e+01, -5.93601112e+01,
-6.00004807e+01, -6.06552086e+01, -6.13225784e+01,
-6.20007973e+01, -6.26880646e+01, -6.33824730e+01,
-6.40822220e+01, -6.47855148e+01, -6.54907074e+01,
-6.61962433e+01, -6.69004745e+01, -6.76018448e+01,
-6.82988281e+01, -6.89898987e+01, -6.96735458e+01,
-7.03481979e+01, -7.10121918e+01, -7.16639557e+01,
-7.23019028e+01, -7.29244461e+01, -7.35300446e+01,
-7.41171265e+01, -7.46841965e+01, -7.52298584e+01,
-7.57526855e+01, -7.62513962e+01, -7.67248459e+01,
-7.71719666e+01, -7.75918121e+01, -7.79834213e+01,
-7.83460007e+01, -7.86789093e+01, -7.89816742e+01,
-7.92538223e+01, -7.94950333e+01, -7.97050018e+01,
-7.98835449e+01, -8.00305862e+01, -8.01461563e+01,
-8.02304077e+01, -8.02836456e+01, -8.03062363e+01,
-8.02987900e+01, -8.02619324e+01, -8.01963196e+01,
-8.01027451e+01, -7.99821243e+01, -7.98353271e+01,
-7.96633453e+01, -7.94671249e+01, -7.92478104e+01,
-7.90065460e+01, -7.87445374e+01, -7.84630661e+01,
-7.81635818e+01, -7.78474579e+01, -7.75161743e+01,
-7.71711807e+01, -7.68137894e+01, -7.64451599e+01,
-7.60662384e+01, -7.56776810e+01, -7.52800369e+01,
-7.48734894e+01, -7.44580231e+01, -7.40333176e+01,
-7.35989304e+01, -7.31542664e+01, -7.26986237e+01,
-7.22311020e+01, -7.17508316e+01, -7.12570038e+01,
-7.07489014e+01, -7.02259598e+01, -6.96877289e+01,
-6.91337738e+01, -6.85638351e+01, -6.79777908e+01,
-6.73756409e+01, -6.67574463e+01, -6.61231613e+01,
-6.54727097e+01, -6.48059692e+01, -6.41226959e+01,
-6.34223747e+01, -6.27042465e+01, -6.19672279e+01,
-6.12100372e+01, -6.04309807e+01, -5.96278610e+01,
-5.87980995e+01, -5.79385986e+01, -5.70459251e+01,
-5.61163254e+01, -5.51455879e+01, -5.41292572e+01,
-5.30626335e+01, -5.19408646e+01, -5.07591400e+01,
-4.95127220e+01, -4.81970291e+01, -4.68076973e+01,
-4.53407593e+01, -4.37926598e+01, -4.21605453e+01,
-4.04422188e+01, -3.86362457e+01, -3.67420464e+01,
-3.47598801e+01, -3.26910439e+01, -3.05377808e+01,
-2.83032646e+01, -2.59916306e+01, -2.36078224e+01,
-2.05195694e+01, -1.64658623e+01, -1.20626736e+01,
-7.90684271e+00, -4.47298717e+00, -2.03672314e+00,
-6.36906505e-01, -8.22197124e-02, 0.00000000e+00], dtype=float32)
##########################################################################
# import libraries
import numpy as np
from numba import jit
import time
Original code
I define 2 functions (rotate_ne_rt
and Grid_Search
) which take n
and e
as inputs.
def rotate_ne_rt(n, e, ba):
if len(n) != len(e):
raise TypeError("North and East component have different length.")
if ba < 0 or ba > 360:
raise ValueError("Back Azimuth should be between 0 and 360 degrees.")
ba = np.radians(ba)
r = - e * np.sin(ba) - n * np.cos(ba)
t = - e * np.cos(ba) + n * np.sin(ba)
return r, t
def Grid_Search(n, e):
energy_1=[]
for angle in np.arange(0, 360, 1):
r, t=rotate_ne_rt(n, e, ba=angle)
average_energy=np.mean(t**2) # Average transverse energy to be minimized
energy_1.append(average_energy)
best_angle=np.argmin(np.array(energy_1))
return best_angle
Following script shows the time spent in execution.
start=time.time()
print(Grid_Search(n, e))
end=time.time()
print("Elapsed (after compilation) = %s" % (end - start))
Code using Numba
I define 2 functions (rotate_ne_rt
and Grid_Search
) which take n
and e
as inputs.
@jit(nopython=True)
def rotate_ne_rt(n, e, ba):
if len(n) != len(e):
raise TypeError("North and East component have different length.")
if ba < 0 or ba > 360:
raise ValueError("Back Azimuth should be between 0 and 360 degrees.")
ba = np.radians(ba)
r = - e * np.sin(ba) - n * np.cos(ba)
t = - e * np.cos(ba) + n * np.sin(ba)
return r, t
@jit(nopython=True)
def Grid_Search(n, e):
energy_1=[]
for angle in np.arange(0, 360, 1):
r, t=rotate_ne_rt(n, e, ba=angle)
average_energy=np.mean(t**2) # Average transverse energy to be minimized
energy_1.append(average_energy)
best_angle=np.argmin(np.array(energy_1))
return best_angle
Following script shows the time spent in execution.
start=time.time()
print(Grid_Search(n, e))
end=time.time()
print("Elapsed (after compilation) = %s" % (end - start))
As you can see, execution is almost 60 times slower when using numba
which is undesirable.
What am I misunderstanding about numba
for this case and is there a way to efficiently use numba
to make my code much faster than not using it?