I'm trying to optimize my code works heavily with numpy functions. I created a simple version for here.
#pythonic.py
import numpy as np
def numpyWithPython():
a = np.random.randint(10, size=5000) -5
b = a[a>0]
c = np.cumprod(b)
d = np.diff(c, prepend=0)
e = np.multiply(d,b)
f = e.copy()
f[f >1] =2
g = np.round(f*5000)
if np.sum(g)>0:
return np.sum(g)
else:
return 20
So basically the whole function works with numpy. Then I compiled it to Cython, I tried my best to optimize but I'm not sure about it, anyway, code looks like this:
#Cythonic.pyx
import numpy as np
cimport numpy as np
# cython: boundscheck=False
# cython: cdivision=True
# cython: wraparound=False
cpdef int numpyWithCython():
cdef np.ndarray[long, ndim=1, mode='c'] a = np.random.randint(10, size=5000) -5
cdef np.ndarray[long, ndim=1, mode='c'] b = a[a>0]
cdef np.ndarray[long, ndim=1, mode='c'] c = np.cumprod(b)
cdef np.ndarray[long, ndim=1, mode='c'] d = np.diff(c, prepend=0)
cdef np.ndarray[long, ndim=1, mode='c'] e= np.multiply(d,b)
cdef np.ndarray[long, ndim=1, mode='c'] f=e.copy()
f[f >1] =2
cdef np.ndarray[long, ndim=1, mode='c'] g =np.round(f*5000)
if np.sum(g)>0:
return np.sum(g)
else:
return 20
And let's compare them
from pythonic import numpyWithPython
from Cythonic import numpyWithCython
import timeit
py = timeit.timeit(numpyWithPython, number=1000)
print("Python : ",py)
cy = timeit.timeit(numpyWithCython, number=1000)
print("Cyhton : ",cy)
Than I get evet negative improvement, which is unexpected...
>>>Python : 0.22221166321079613
>>>Cyhton : 0.23356160436067247
Is my optimization for Cython wrong or in this case Numpy is already fast so Cython makes no sense?
Should I go with native python arrays to speed up, or what can I do to go faster?