En esta publicación, "máquina virtual" hace referencia a las máquinas virtuales de proceso, no a las máquinas virtuales de sistema como Qemu o Virtualbox. Una máquina virtual de proceso es , simplemente un programa que proporciona un entorno de programación general, un programa que se puede programar.
Java tiene un intérprete, así como una máquina virtual, y Python tiene una máquina virtual , así como un intérprete. La razón "máquina virtual" es un término común más en Java y "intérprete" es un término más común en Python que tiene mucho que ver con la diferencia entre los dos idiomas: tipado estático Pitón).En este contexto, "tipo" hace referencia a primitive data types - tipos que sugieren el tamaño de almacenamiento en memoria de los datos. La máquina virtual Java lo tiene fácil. Requiere que el programador especifique el tipo de datos primitivo de cada variable. Esto proporciona suficiente información para bytecode Java no solo para ser interpretada y ejecutada por la máquina virtual Java , sino incluso para ser compiled into machine instructions. La máquina virtual Python es más compleja en el sentido de que lleva a cabo la tarea adicional de detener antes de la ejecución de cada operación para determinar los tipos de datos primitivos para cada variable o estructura de datos involucrada en la operación . Python libera al programador de pensar en términos de tipos de datos primitivos , y permite que las operaciones se expresen en un nivel superior. El precio de esta libertad es el rendimiento. "Intérprete" es el término preferido para Python porque tiene que detenerse para inspeccionar los tipos de datos, y también porque la sintaxis relativamente concisa de de los lenguajes de tipo dinámico es una buena opción para las interfaces interactivas . No existe una barrera técnica para construir una interfaz interactiva de Java , pero tratar de escribir de forma interactiva cualquier código estáticamente sería tedioso, por lo que simplemente no se hace de esa manera.
En el mundo Java, la máquina virtual se roba el show porque se ejecuta programas escritas en un idioma que en realidad pueden ser compilados en instrucciones de máquina, y el resultado es la velocidad y la eficiencia de los recursos. Java bytecode se puede ejecutar por la máquina virtual Java con un rendimiento similar al de los programas compilados , en términos relativos. Esto se debe a la presencia de información de tipo de datos primitivos en el bytecode. La máquina virtual Java pone de Java en una categoría de su propia:
portátil interpretó estáticamente mecanografiada lenguaje
Lo siguiente más cercano es LLVM, pero LLVM opera a un nivel diferente:
interpretado portátil lenguaje ensamblador
El término "código de bytes" se utiliza tanto en Java y Python, pero no todo el código de bytes se iguales. bytecode es simplemente el término genérico para los lenguajes intermedios utilizados por compiladores/intérpretes. Incluso los compiladores C como gcc usan un intermediate language (or several) para hacer el trabajo. El bytecode de Java contiene información sobre tipos de datos primitivos, mientras que el bytecode de Python no. En este aspecto, la máquina virtual Python (y Bash, Perl, Ruby, etc.) es realmente fundamentalmente más lenta que la máquina virtual Java, o más bien, simplemente tiene más trabajo por hacer.Es útil tener en cuenta qué tipo de información está contenida en diferentes formatos de código de bytes:
- llvm: Registros de la CPU
- Java: tipos de datos primitivos
- Python: tipos definidos por el usuario
Para dibujar una analogía del mundo real: LLVM trabaja con átomos, la máquina virtual Java trabaja con moléculas, y la máquina virtual Python trabaja con materiales. Dado que todo debe descomponerse finalmente en partículas subatómicas (operaciones de máquina reales ), la máquina virtual Python tiene la tarea más compleja.
Los intérpretes/compiladores de idiomas con tipado estático no tienen el mismo equipaje que tienen los intérpretes/compiladores de lenguajes de tipado dinámico. Los programadores de idiomas con tipado estático tienen que ocupar la holgura, para lo cual el pago es el rendimiento. Sin embargo, al igual que todas las funciones no deterministas son secretamente deterministas, también lo son secretamente estáticamente tipados. Por lo tanto, las diferencias de rendimiento entre las dos familias de lenguas deben nivelar todo el tiempo Python cambia su nombre a HAL 9000.
Las máquinas virtuales de los lenguajes dinámicos como Python implementar alguna máquina lógica idealizada , y no necesariamente se corresponden muy de cerca a cualquier hardware físico real . La máquina virtual Java, en cambio, es más similar en la funcionalidad a un compilador clásico de C, excepto que en lugar de emitir instrucciones de la máquina , ejecuta rutinas incorporadas. En Python, un número entero es un objeto de Python con un conjunto de atributos y métodos asociados. En Java, un int es un número designado de bits, por lo general 32. No es realmente una comparación justa . Los enteros de Python realmente deberían compararse con la clase entera Java . El tipo de datos primitivo "int" de Java no se puede comparar con nada en el lenguaje Python, porque el lenguaje Python simplemente carece de esta capa de primitivas , y lo mismo ocurre con el bytecode de Python.
Dado que las variables Java se escriben de forma explícita, uno puede esperar razonablemente algo así como Jython rendimiento para estar en el mismo estadio de béisbol como cPython. Por otro lado, es casi seguro que una máquina virtual Java implementada en Python sea más lenta que el lodo. Y no espere que Ruby, Perl, etc., le vaya mejor. No fueron diseñados para hacer eso. Fueron diseñados para "scripting", que es lo que se llama programación en un lenguaje dinámico.
Cada operación que tiene lugar en una máquina virtual finalmente tiene que golpear el hardware real. Las máquinas virtuales contienen rutinas pre compiladas que son lo suficientemente generales como para ejecutar cualquier combinación de operaciones lógicas. Una máquina virtual puede no emitir nuevas instrucciones de máquina, pero sin duda está ejecutando sus propias rutinas una y otra vez en secuencias complejas. La máquina virtual Java, la máquina virtual Python y todas las otras máquinas virtuales de uso general que existen son iguales en el sentido de que se las puede convencer para que realicen cualquier lógica que se les ocurra, pero son diferentes en términos de las tareas que asumir, y qué tareas le dejan al programador.
Psyco para Python no es una máquina virtual completa de Python, pero un compilador justo a tiempo que secuestra la máquina virtual de Python regular en puntos que piensa que puede compilar unas pocas líneas de código - bucles sobre todo donde cree que el tipo primitivo de alguna variable permanecerá constante incluso si el valor cambia con en cada iteración. En ese caso, puede prescindir de la determinación incesante tipo de la máquina virtual normal. Sin embargo, debes tener un poco de cuidado, , para que no saques el tipo de debajo de los pies de Psyco. Pysco, sin embargo, normalmente sabe simplemente recurrir a la máquina virtual normal si no es completamente seguro de que el tipo no cambiará.
La moraleja de la historia es que la información del tipo de datos primitivos es realmente útil para un compilador/máquina virtual.
Por último, para poner todo en perspectiva considere esto: un programa de Python ejecutado por una máquina intérprete de Python/virtual implementado en Java que se ejecuta en un intérprete máquina Java/Virtual implementado en LLVM se ejecuta en un qemu virtuales máquina en marcha en un iPhone.
permalink
Tenía la impresión de que Python generó código de bytes, pyc, o es a lo que te refieres con "ayudar a acelerar tales idiomas interpretados, aquí es donde podemos definir formas intermedias de código fuente pre-analizado y pre-tokenizado que es más fácilmente interpretado directamente ". –
@InSciTek Jeff: De su respuesta no está claro si usted sabe que Python también usa una máquina virtual. – tzot
@TZ - La implementación popular de Python es un compilador de Python con una máquina virtual secundaria. En el modo interactivo, es un poco híbrido con una interfaz de intérprete y un final de compilación. Sin embargo, esas son las opciones de implementación. Traté de describir la diferencia entre el concepto de VM e Intérprete –