¿Por qué no hay un compilador de Python para el código de máquina nativo?

25

Según tengo entendido, la causa de la diferencia de velocidad entre los lenguajes compilados y Python es que el primer código compila todo el código de la máquina nativa, mientras que Python compila al código de bytes python, para ser interpretado por el PVM. Veo que de esta manera los códigos de Python se pueden usar en múltiples sistemas operativos (al menos en la mayoría de los casos), sin embargo, no entiendo, ¿por qué no hay un compilador adicional (y opcional) para Python, que se compila de la misma manera que los compiladores tradicionales? . Esto dejaría al programador elegir, lo cual es más importante para ellos; Ejecución o rendimiento multiplataforma en máquina nativa. En general; ¿Por qué no hay idiomas que puedan comportarse como compilados e interpretados?

usuario2986898
fuente
44
No es . Haskell también puede comportarse como compilado o interpretado a través de GHCI
toasted_flakes
C ++ también tiene intérpretes . Y probablemente toneladas de otros idiomas tienen ambas implementaciones.
Claudio
2
En realidad, eligiendo IronPythong ( ironpython.net ) y compilar el código IL producido por el uso de "NGEN" ( msdn.microsoft.com/de-de/library/6t9t5wcf%28v=vs.110%29.aspx ) no es una forma compilar Python al código de máquina nativo. No es que haya probado esa cadena de herramientas.
Doc Brown
10
Uno puede escribir compiladores de Python a nativo. Simplemente no son muy interesantes porque en realidad no mejoran el rendimiento por un margen significativo, a menos que realmente implementen un lenguaje que se parezca a Python pero que sea mucho más restringido. Me explicó previamente en otro lugar por qué.

Respuestas:

29

No. La razón por la cual existen diferencias de velocidad entre lenguajes como Python y C ++ es porque los lenguajes de tipo estático le brindan al compilador toneladas de información sobre la estructura del programa y sus datos, lo que le permite optimizar tanto los cálculos como el acceso a la memoria. Debido a que C ++ sabe que la variable es de tipo int, puede determinar la forma óptima de manipular esa variable incluso antes de ejecutar el programa. En Python, por otro lado, el tiempo de ejecución no sabe qué valor hay en una variable justo hasta que el intérprete alcanza la línea. Esto es extremadamente importante para las estructuras, donde en C ++, el compilador puede determinar fácilmente el tamaño de la estructura y cada ubicación de sus campos dentro de la memoria durante la compilación. Esto le da un gran poder para predecir cómo se podrían usar los datos y le permite optimizar de acuerdo con esas predicciones.

Para compilar efectivamente lenguajes como Python, necesitarías:

  1. Asegúrese de que la estructura de datos sea estática durante la ejecución del programa. Esto es problemático porque Python tiene eval y metaclases. Ambos que hacen posible cambiar la estructura del programa en función de la entrada del programa. Esta es una de las cosas que le dan a Python tal poder expresivo.
  2. Inferir los tipos de todas las variables, estructuras y clases desde el propio código fuente. Si bien es posible hasta cierto punto, el sistema de tipo estático y el algoritmo serían tan complejos que sería casi imposible implementarlos de manera utilizable. Podría hacerlo para un subconjunto del idioma, pero definitivamente no para todo el conjunto de características del idioma.
Eufórico
fuente
66
Vale la pena señalar que esto hace que el problema sea difícil , pero no imposible. sbcl compila Common Lisp, que también es dinámico, tiene evaly un montón de otras cosas para entristecer a los escritores de compiladores. No está al nivel de gcc, pero ciertamente es más rápido que el intérprete de CPython.
Daniel Gratzer
3
@jozefg dije efectivamente compilar. No solo compilar. Python también tiene su compilador Cython que produce código nativo. El punto es que esos compiladores no pueden hacer ni siquiera una fracción de las optimizaciones que los compiladores para lenguajes de tipo estático pueden hacer. Y cuando compare el rendimiento, compárelo con C ++ compilado y Python no interpretado.
Eufórico
2
Bueno, en realidad, te sorprendería lo que puede hacer sbcl. El juego de puntos de referencia muestra que se ejecuta tan rápido como Java, casi tan rápido como GHC, y dentro de 1x a 10x de C. No es lento para ningún estándar. Sí, los tipos dinámicos inhiben la compilación en cierta medida, pero no tanto como parece.
Daniel Gratzer
3
Comparar la velocidad de Python interpretado con Python compilado es interesante en sí mismo. Deja de decir "usa C ++". Quizás ya tenga el código escrito en Python. Quizás el código sea más fácil de escribir en python. A quien le importa. Lo que me importa es una velocidad 1.5x (lo que sea). Eso puede hacer una gran diferencia.
Thomas Eding
3
En otras palabras, si desea compilar, elija otro idioma que esté ajustado para eso, como C ++ o Pascal.
Please_Dont_Bully_Me_SO_Lords
0

Dos conceptos podrían ayudarnos a comprender mejor por qué Python compilado en código máquina nativo "puede" no ejecutarse tan rápido como C compilado u otros lenguajes compilados comúnmente. Se llaman unión temprana y unión tardía.

Debería comenzar diciendo que no soy un experto en Python, y vine a este sitio por accidente. Pero me gusta este sitio.

Como se mencionó en otra respuesta aquí, el compilador de C ++ puede saber mucho sobre el programa y tomar decisiones sobre qué operaciones usar para estructuras de datos específicas. Como ejemplo, si se deben agregar dos variables enteras, el compilador sabe que son enteros nativos, de 32 bits de ancho, por ejemplo, y puede agregarlos junto con una instrucción "ADD". Por lo tanto, compila la instrucción ADD en el código. Está bloqueado y no se puede cambiar mientras el programa se está ejecutando. Eso es vinculante temprano.

Por otro lado, en un lenguaje como Python, podríamos esperar que el programa arroje diferentes tipos de datos juntos de formas complejas. Ahora el compilador no sabe si nuestras 2 variables son enteros, flotantes, cadenas o listas. Por lo tanto, tiene que compilar el código que determina esa información en tiempo de ejecución y seleccionar la operación correcta mientras se ejecuta el programa. Esto es vinculante tarde y podemos entender que habrá un impacto en el rendimiento por hacer ese trabajo adicional mientras se ejecuta el programa. Es el precio que paga por mantener abiertas esas opciones en un lenguaje como Python, pero proporciona la máxima flexibilidad de tiempo de ejecución.

usuario214354
fuente
-4

Creo que tiene más que ver con los detalles de Python en sí, la misma razón por la que no puedes compilar C # en el código de la máquina. Los detalles del lenguaje en realidad podrían hacer que sus programas tengan errores, incluso si fuera posible debido a la naturaleza del lenguaje. ¿Por qué no solo aprender el lenguaje C? Es mucho más fácil que C ++ y ligeramente avanzado que Python, pero aún accesible.

Rápido
fuente
55
C # puede ir directamente al código de máquina: Lenguaje intermedio común: compilación anticipada - "Los entornos de ejecución compatibles con CLI también vienen con la opción de hacer una compilación anticipada (AOT) de un ensamblaje para que se ejecute más rápido al eliminarlo el proceso JIT en tiempo de ejecución. En .NET Framework hay una herramienta especial llamada Native Image Generator (NGEN) que realiza el AOT. En Mono también hay una opción para hacer un AOT ".