Estoy empezando a aprender Cython debido a problemas de rendimiento. Este código en particular es un intento de implementar algunos algoritmos nuevos en el área de modelado de transporte (para planificación).¿Por qué este código es más lento en Cython que en Python?
Decidí comenzar con una función muy simple que utilizaré MUCHO (cientos de millones de veces) y definitivamente me beneficiaría de un aumento en el rendimiento.
he implementado esta función de tres maneras diferentes y las probaron para el mismo parámetro (por motivos de simplicidad) para 10 millones de veces cada uno:
- código Cython en un módulo Cython. Tiempo de ejecución: 3.35s
- Código de Python en un módulo de Cython. Tiempo de ejecución: 4.88s
código de Python en el script principal. Tiempo de ejecución: 2.98s
Como puede ver, el código cython fue un 45% más lento que el código python en un módulo cython y un 64% más lento que el código escrito en el script principal. ¿Cómo es eso posible? ¿Dónde estoy cometiendo un error?
El código Cython es la siguiente:
def BPR2(vol, cap, al, be):
con=al*pow(vol/cap,be)
return con
def func (float volume, float capacity,float alfa,float beta):
cdef float congest
congest=alfa*pow(volume/capacity,beta)
return congest
Y el guión para la prueba es el siguiente:
agora=clock()
for i in range(10000000):
q=linkdelay.BPR2(10,5,0.15,4)
agora=clock()-agora
print agora
agora=clock()
for i in range(10000000):
q=linkdelay.func(10,5,0.15,4)
agora=clock()-agora
print agora
agora=clock()
for i in range(10000000):
q=0.15*pow(10/5,4)
agora=clock()-agora
print agora
Estoy al tanto de temas como funciones trascendentales (potencia) siendo más lenta, pero yo no, creo que debería ser un problema.
Dado que hay una sobrecarga para buscar la función en el espacio de funciones, ¿ayudaría el rendimiento si pasé una matriz para la función y obtuve una matriz? ¿Puedo devolver una matriz usando una función escrita en Cython?
Como referencia, estoy usando: - Windows 7 64bits - Python 2.7.3 64 Bits - Cython 0.16 64 bits - Windows Visual Studio 2008
Entonces, si está pensando en pasar una matriz en la función, presumiblemente puede vectorizar el código, en cuyo caso ha considerado hacer ¿Qué estás tratando de hacer simplemente con [NumPy] (http://numpy.scipy.org/)? Ciertamente, la función en su ejemplo se puede implementar trivialmente en arreglos usando NumPy. –
Bueno, es una función extremadamente trivial y cython tiene que convertir el 'PyObject *' en un flotador y luego ¿no? Parece una sobrecarga para una función tan pequeña. – Voo
Solo para aclarar, su problema es que pasa la mayor parte de su tiempo llamando a la función, que no se mejora al usar Cython. Le sugiero que reformule su pregunta sin perjudicar la solución (Cython). De esa manera, aquellos que suelen contestar tendrán más para trabajar. Un pequeño ejemplo de cómo usas realmente el código sería útil. –