2010-04-23 15 views
35

Me encontré con Cython, mientras buscaba formas de optimizar el código de Python. Leí varias publicaciones en stackoverflow, la wiki de python y leí el artículo "Reglas generales para la optimización".Cython Speed ​​Boost vs. Usabilidad

Cython es algo que capta mi interés más; en lugar de escribir C-code para usted, puede elegir tener otros tipos de datos en su código python.

Aquí está una prueba tonta he intentado,

#!/usr/bin/python 
# test.pyx 
def test(value): 
    for i in xrange(value): 
    i**2 
    if(i==1000000): 
     print i 

test(10000001) 

$ pitón tiempo test.pyx

real 0m16.774s 
user 0m16.745s 
sys  0m0.024s 

$ Cython tiempo test.pyx

real 0m0.513s 
user 0m0.196s 
sys  0m0.052s 

Ahora, honestamente, i Estoy estupefacto. El código que he usado aquí es puro código python, y todo lo que he cambiado es el intérprete. En este caso, si cython es así de bueno, ¿por qué la gente todavía usa el intérprete tradicional de Python? ¿Hay algún problema de confiabilidad para Cython?

+14

Está midiendo el tiempo de ejecución de un script de Python en comparación con el tiempo de compilación de algún código de Cython. Eso no tiene sentido. –

+2

En cuanto a su última observación: eso es básicamente lo que intenta hacer Julia: crear un traductor de código de bajo nivel optimizado en un lenguaje de máquina coherente de alto nivel, y mostrar claramente esta intención desde el principio para obtener una mejor tracción incluso si significa que algunas características de alto nivel se pierden en el camino, como el tipado dinámico. – gaborous

+1

@SturlaMolden: ¿No es esta una prueba de Python interpretar vs Cython copilar y ejecutar? Si es así, tiene perfecto sentido. – Eddy

Respuesta

50

Las otras respuestas ya explicaron cómo estaba compilando el código de Cython, no ejecutándolo. Sin embargo, pensé que podría querer saber cuánto más rápido Cython puede hacer su código. Cuando compilé el código que tiene (aunque ejecuté la función desde un módulo diferente) con distutils, obtuve ganancias de velocidad muy marginales con respecto a Python directo: alrededor del 1%.Sin embargo, cuando he añadido algunos pequeños cambios en su código:

def test(long long value): 
    cdef long long i 
    cdef long long z 
    for i in xrange(value): 
     z = i**2 
     if(i==1000000): 
      print i 
     if z < i: 
      print "yes" 

y compilado, lo tengo los siguientes tiempos:

  • código Python puro: 20,4553578737 segundo
  • código
  • Cython : 0.199339860234 segundos

Eso es una aceleración de 100 ×. No está nada mal.

+27

Posiblemente tiene el precio de ser correcto. El código de Python calcula el valor correcto de 'i ** 2'. El código C se desborda para la mayoría de los números para los que realiza la operación si está compilando código de 32 bits. (Si realiza la operación. Es concebible que su compilador de C optimice la operación por completo). Probablemente esta no sea una comparación justa. Tampoco has dejado completamente claro qué estás ejecutando, cómo lo estás ejecutando y qué estás cronometrando cuando das esos tiempos. –

+0

Dicho sea de paso, este es el tipo de cosas que quise decir con "rarezas". Casi proporciono el ejemplo de desbordamiento como cuando el código de Python realiza automáticamente comprobaciones que aseguran la corrección y que podrían fallar de manera silenciosa en C. –

+6

Tiene razón. Pensé en el desbordamiento mientras lo hacía, pero era flojo porque sabía que realmente no importaba en este caso. Lo arreglaré para usar largos largos. –

18

Cython no es otro intérprete. Genera c-extensions para python, a partir del código python (-like). cython test.pyx solo generará un archivo 'test.c', que (una vez compilado) puede ser utilizado por python como una biblioteca normal de python.

Eso significa que solo está midiendo el tiempo que le toma a cython traducir su código python a c, no la velocidad con la que se ejecuta esa versión de su código.

+4

Sí, para cualquiera que desee que cython realmente compilara y ejecutara su programa en una línea, creé runcython (https://github.com/russell91/runcython). 'runcython test.pyx' tendrá la semántica que el OP pretendía. – RussellStewart

9
  • cython test.pyx no ejecuta realmente su programa. El binario cython es para procesar su código Cython en un módulo de extensión Python. Tendría que importarlo en Python para ejecutarlo.

  • #!/usr/bin/python no es la mejor línea shebang para scripts de Python. Generalmente se prefiere #!/usr/bin/env python, que ejecuta lo que python haría en la línea de comando.

    • Cython pyx archivos probablemente no deberían tener una línea tinglado en todos, excepto en el caso de esquina que son programas Python válidos.
  • Tiene un IndentationError en el código publicado.

  • El uso del intérprete tradicional es más simple y portátil. Cython es confiable, pero tiene sus limitaciones y peculiaridades. Podría ser convincente usarlo muchísimo más si, por arte de magia, le diera las aceleraciones que los tiempos hacen parecer, pero en realidad le da a los más pequeños. Tendrás que empezar a usar funciones específicas de Cython para usar las funciones C para ver mucha aceleración.

9

Un punto importante que parece faltar: Cython no es un superconjunto estricto de Python. Hay algunas características que admite Python, pero Cython no. En particular, generadores y lambdas (pero vienen).

+2

¿sabes si llegaron todavía? –

2
  • La razón más grande que Cython no es tan popular es que carece de ejecutables independientes (sin python).

  • Falta de publicidad. Los desarrolladores parecen ser académicos más interesados ​​en Desarrollar su software Sage, que un lenguaje de vanguardia.

  • Errores encontrados durante el desarrollo. Uno que encontré es la falta de soporte verdadero de subprocesos. Todo está envuelto en un bloqueo de intérprete global, por lo que es seguro para los hilos, ¡pero desactiva la concurrencia!

+6

Puede liberar el GIL cuando no sea necesario.Es entonces cuando no estás usando la API de Python C. En Cython esto se escribe como "with nogil:", y obtendrá un error cuando liberar el GIL no es seguro. Los subprocesos de Python son subprocesos nativos del sistema operativo y le darán concurrencia cuando se lance GIL. Eso es cierto para Python y Cython por igual. –

+0

Según [wikipedia] (https://en.wikipedia.org/wiki/Global_interpreter_lock) CPython (es decir, Python) usa GIL y, como tal, sus capacidades de paralelismo/concurrencia no son mejores que las de Cython. –