¿Convertir el programa Python a código C / C ++? [cerrado]


149

¿Es posible convertir un programa Python a C / C ++?

Necesito implementar un par de algoritmos, y no estoy seguro de si la brecha de rendimiento es lo suficientemente grande como para justificar todo el dolor que pasaría al hacerlo en C / C ++ (en lo que no soy bueno). Pensé en escribir un algoritmo simple y compararlo con una solución convertida. Si solo eso es significativamente más rápido que la versión de Python, entonces no tendré otra opción que hacerlo en C / C ++.


32
Por mucho que Python pierda en los puntos de referencia, tenga en cuenta que esa desaceleración de 50x o 100x sigue siendo descuidada si el cálculo finaliza en unos segundos en Python, y ni siquiera es cierto cuando realiza muchas E / S o tiene un algoritmo horrible. En lugar de preguntar "¿cuánto más lento es Python?" debes preguntar "¿Python es lo suficientemente rápido?" (y lo más probable es que, sinceramente), eso también sea más rápido que hacer una evaluación comparativa o preguntar aquí.

1
Implementar un algoritmo en python es bastante rápido y directo ... simplemente tiene que hacerlo y luego verificar si es lo suficientemente rápido. La mayoría de las veces puede optimizar el algoritmo para que se ejecute mucho más rápido utilizando diferentes estructuras de datos (dict / sets en lugar de listas ...) u operaciones diferentes. De todos modos, la optimización debería ocurrir después de que ya haya implementado un primer borrador del algoritmo y lo haya comparado / perfilado.
Bakuriu

@delnan: en mi caso, todo se trata del tiempo de cálculo. Si la variante C necesita x horas menos, entonces invertiría ese tiempo en dejar que los algoritmos funcionen por más tiempo / nuevamente. Simplemente quiero averiguar (aproximadamente) cuánto más lento sería Python: si solo son un par de horas, ciertamente no usaría un lenguaje con el que no me sienta cómodo (puede arruinar las mejores soluciones a problemas con malas implementaciones: PAGS).
CrazyFlyingCloseline

@ delnan tiene razón sobre que Python probablemente sea lo suficientemente rápido para muchas cosas. Incluso cuando es más lento, la facilidad de desarrollo, mantenimiento y mejoras futuras son factores importantes a considerar.
Martineau

"x horas"? ¿Qué tan grande es esto? ¿Ha comparado una implementación? ¿Tienes medidas? ¿Has perfilado la implementación? ¿O estás tratando de optimizar prematuramente la solución?
S.Lott

Respuestas:


115

Si. Mira a Cython . Hace exactamente eso: Convierte Python a C para acelerar.


66
Por supuesto, eso no le ahorrará nada a menos que agregue un montón de cdefdeclaraciones y, por lo tanto, introduzca una escritura estática (de lo contrario, solo hará malabarismos con PyObject *cosas opacas ). Y nunca será tan rápido como el C simple porque usualmente interactúa con Python (¿100% o más? ¡Solo para un código numérico simple que no interactúa con Python en la mayor parte del tiempo!). Pero aparte de eso, sí, puede obtener una aceleración bastante ingeniosa.

77
@delnan: De hecho, te ahorra algo. La mayoría del código Python puro será más rápido después de compilado. Pero sí, con los cdefs y la escritura estática realmente empiezas a ver diferencias. Y la interfaz con Python se obtiene en todos los casos en los que usa C de Python.
Lennart Regebro

136

Si la variante C necesita x horas menos, entonces invertiría ese tiempo en dejar que los algoritmos funcionen por más tiempo / nuevamente

"invertir" no es la palabra correcta aquí.

  1. Construya una implementación funcional en Python. Terminarás esto mucho antes de terminar una versión C.

  2. Mida el rendimiento con el generador de perfiles de Python. Solucione cualquier problema que encuentre. Cambie las estructuras de datos y los algoritmos según sea necesario para realmente hacer esto correctamente. Terminarás esto mucho antes de terminar la primera versión en C.

  3. Si todavía es demasiado lento, traduzca manualmente el Python bien diseñado y cuidadosamente construido a C.

    Debido a la forma en que funciona la retrospectiva, hacer la segunda versión de Python existente (con las pruebas unitarias existentes y con los datos de perfiles existentes) seguirá siendo más rápido que intentar hacer el código C desde cero.

Esta cita es importante.

La regla de Thompson para los fabricantes de telescopios por primera vez
Es más rápido hacer un espejo de cuatro pulgadas y luego un espejo de seis pulgadas que hacer un espejo de seis pulgadas.


Instituto Bill McKeenan Wang


15
Independientemente del tremendo puntaje, no veo cómo responde esto a la pregunta.
Audrius Meskauskas

29

Shed Skin es "un compilador de Python a C ++ (restringido)".


3
+1 una ventaja de Shed Skin es la inferencia de tipos : si es posible adivinar los tipos de variables del flujo del programa, se evita la verificación dinámica de tipos. Esto generalmente conduce a un código C ++ más corto que en realidad es posible leer y compila en programas más rápidos.
Kyss Tao

1
También hay un transpilador Python → 11l → C ++ , que también es un compilador restringido de Python a C ++, pero admite algunas características de Python, que no es compatible con Shed Skin (por ejemplo, funciones / cierres anidados).
tav

17

Acabo de encontrar esta nueva herramienta en las noticias de hackers.

Desde su página: "Nuitka es un buen reemplazo para el intérprete de Python y compila cada construcción que ofrecen CPython 2.6, 2.7, 3.2 y 3.3. Traduce Python en un programa C ++ que luego utiliza" libpython "para ejecutar de la misma manera que CPython lo hace, de una manera muy compatible ".


Este proyecto es mucho más maduro que otras opciones similares. Es curioso que crea el binario con una .exeextensión en OSX a pesar de que es un ejecutable perfectamente normal OSX Mach-O. Parece que podría ser un buen reemplazo para pyinstaller, py2exe, py2app, etc. Las --recurse-***banderas son importantes para configurar correctamente sin embargo.
ccpizza

Nuitka es genial, pero el código C / C ++ creado está usando PyObject que se une a la implementación de código CPython-C. No produce código C idiomático.
Make42

8

Otra opción, para convertir a C ++ además de Shed Skin , es Pythran .

Para citar Python de alto rendimiento de Micha Gorelick e Ian Ozsvald :

Pythran es un compilador de Python a C ++ para un subconjunto de Python que incluye numpysoporte parcial . Actúa un poco como Numba y Cython: anota los argumentos de una función, y luego se hace cargo con más anotaciones de tipo y especialización de código. Aprovecha las posibilidades de vectorización y las posibilidades de paralelización basadas en OpenMP. Se ejecuta solo con Python 2.7.

Una característica muy interesante de Pythran es que intentará detectar automáticamente las oportunidades de paralelización (por ejemplo, si está utilizando a map), y convertir esto en código paralelo sin requerir un esfuerzo adicional de su parte. También puede especificar secciones paralelas usando las pragma omp directivas>; a este respecto, se siente muy similar al soporte OpenMP de Cython.

Detrás de escena, Pythran tomará tanto Python normal como código numpy e intentará compilarlos agresivamente en C ++ muy rápido, incluso más rápido que los resultados de Cython.

Debe tener en cuenta que este proyecto es joven y puede encontrar errores; También debe tener en cuenta que el equipo de desarrollo es muy amigable y tiende a corregir errores en cuestión de horas.


6

Sé que este es un hilo antiguo pero quería dar lo que creo que es información útil.

Personalmente uso PyPy, que es realmente fácil de instalar usando pip. Uso indistintamente el intérprete de Python / PyPy, no necesita cambiar su código en absoluto y he descubierto que es aproximadamente 40 veces más rápido que el intérprete de Python estándar (Python 2x o 3x). Uso pyCharm Community Edition para administrar mi código y me encanta.

Me gusta escribir código en Python, ya que creo que te permite concentrarte más en la tarea que en el lenguaje, lo cual es una gran ventaja para mí. Y si necesita que sea aún más rápido, siempre puede compilar en un binario para Windows, Linux o Mac (no sencillo pero posible con otras herramientas). Según mi experiencia, obtengo una aceleración de 3.5x sobre PyPy al compilar, lo que significa 140x más rápido que Python. PyPy está disponible para código Python 3x y 2x y, de nuevo, si usa un IDE como PyCharm, puede intercambiar entre PyPy, Cython y Python muy fácilmente (aunque requiere un poco de aprendizaje inicial y configuración).

Algunas personas pueden discutir conmigo sobre esto, pero creo que PyPy es más rápido que Cython. Pero ambas son excelentes opciones.

Editar: me gustaría hacer otra nota rápida sobre la compilación: cuando compila, el binario resultante es mucho más grande que su script de Python, ya que crea todas las dependencias en él, etc. Pero luego obtiene algunos beneficios distintos: ¡velocidad! ahora la aplicación funcionará en cualquier máquina (dependiendo del sistema operativo para el que compiló, si no todos. lol) sin Python o bibliotecas, también ofusca su código y está técnicamente listo para la 'producción' (hasta cierto punto). Algunos compiladores también generan código C, que realmente no he visto ni visto si es útil o simplemente galimatías. Buena suerte.

Espero que ayude.


2
Sé que este es un comentario anterior, ¡pero gracias!
kfrncs

No hay problema, me alegro de que haya sido útil.
Jacktrader

¿Qué software utilizas para compilar a partir de la interpretación PyPy?
Vasyl Vaskivskyi

No específicamente PyPy, solo scripts .py. Nuitka si quieres "ejecutables C / C ++ o código fuente C / C ++" y PyInstaller si solo quieres un ejecutable (más fácil). También hay py2exe, pero tuve menos éxito con él, aunque estoy seguro de que las cosas han mejorado. PyInstaller también es multiplataforma, no solo para ejecutables de Windows (funciona con Linux y Mac). Nuitka es único porque creo que es el único "compilador" que le devuelve el código fuente utilizable que, en teoría, podría optimizar aún más. Hay algunos otros como bbFreeze, cx_Freeze y py2app, pero no los he probado. ¡La mejor de las suertes!
Jacktrader

1
También he encontrado que PyPy se ejecuta más rápido que Cython. En una prueba, en realidad encontré que PyPy tenía la misma velocidad que una versión C ++ del programa (clasificación de inserción).
Nv7

5

Me doy cuenta de que falta una respuesta sobre una solución bastante nueva. Si se usa Numpy en el código, recomendaría probar Pythran:

http://pythran.readthedocs.io/

Para las funciones que probé, Pythran da resultados extremadamente buenos. Las funciones resultantes son tan rápidas como el código Fortran bien escrito (o solo un poco más lento) y un poco más rápido que la solución Cython (bastante optimizada).

La ventaja en comparación con Cython es que solo tiene que usar Pythran en la función Python optimizada para Numpy, lo que significa que no tiene que expandir los bucles y agregar tipos para todas las variables en el bucle. Pythran se toma su tiempo para analizar el código para comprender las operaciones numpy.ndarray.

También es una gran ventaja en comparación con Numba u otros proyectos basados ​​en la compilación justo a tiempo para los cuales (que yo sepa), debe expandir los bucles para ser realmente eficiente. Y luego el código con los bucles se vuelve muy ineficiente usando solo CPython y Numpy ...

Un inconveniente de Pythran: ¡no hay clases! Pero como solo se deben compilar las funciones que realmente necesitan ser optimizadas, no es muy molesto.

Otro punto: Pythran admite bien (y muy fácilmente) el paralelismo de OpenMP. Pero no creo que mpi4py sea compatible ...


4

http://code.google.com/p/py2c/ parece una posibilidad: también mencionan en su sitio: Cython, Shedskin y RPython y confirman que están convirtiendo el código Python a C / C ++ puro, que es mucho más rápido que C / C ++ plagado de llamadas a la API de Python. Nota: No lo he probado pero voy a ...


1
Parece que Py2C sigue siendo un proyecto inacabado. No se ha actualizado en algunos años, por lo que podría estar difunto.
Anderson Green
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.