compilation - que - ¿Qué hace un compilador Just-In-Time(JIT)?
que es just in time (18)
Al principio, un compilador era responsable de convertir un lenguaje de alto nivel (definido como un nivel más alto que el ensamblador) en un código objeto (instrucciones de máquina), que luego se vincularía (mediante un enlazador) en un ejecutable.
En un momento de la evolución de los idiomas, los compiladores compilarían un lenguaje de alto nivel en pseudocódigo, que luego sería interpretado (por un intérprete) para ejecutar su programa. Esto eliminó el código objeto y los ejecutables, y permitió que estos lenguajes fueran portátiles a múltiples sistemas operativos y plataformas de hardware. Pascal (que compiló a P-Code) fue uno de los primeros; Java y C # son ejemplos más recientes. Finalmente, el término P-Code fue reemplazado por el bytecode, ya que la mayoría de las pseudo-operaciones son un byte de largo.
Un compilador Just-In-Time (JIT) es una característica del intérprete de tiempo de ejecución, que en lugar de interpretar el código de bytes cada vez que se invoca un método, compilará el código de bytes en las instrucciones del código de máquina de la máquina en ejecución y luego invocará este código objeto en su lugar. Idealmente, la eficiencia de ejecutar el código de objeto superará la ineficiencia de recompilar el programa cada vez que se ejecuta.
¿Qué hace un compilador JIT específicamente en comparación con un compilador no JIT? ¿Alguien puede dar una descripción sucinta y fácil de entender?
Como han mencionado otros
JIT significa Just-in-Time, lo que significa que el código se compila cuando es necesario, no antes del tiempo de ejecución.
Solo para agregar un punto a la discusión anterior, JVM mantiene un conteo de la cantidad de tiempo que se ejecuta una función. Si este recuento excede un límite predefinido, JIT compila el código en un lenguaje de máquina que puede ser ejecutado directamente por el procesador (a diferencia del caso normal en el que javac compila el código en el código de bytes y luego en java: el intérprete interpreta este código de bytes por línea lo convierte en código de máquina y se ejecuta).
Además, la próxima vez que se calcule esta función, se ejecutará nuevamente el mismo código compilado, a diferencia de la interpretación normal en la que el código se interpreta nuevamente línea por línea. Esto hace que la ejecución sea más rápida.
El 20% del código de bytes se utiliza el 80% del tiempo. El compilador JIT obtiene estas estadísticas y optimiza este 20% del código de bytes para que se ejecute más rápido agregando métodos en línea, eliminando bloqueos no utilizados, etc. y también creando el código de bytes específico de esa máquina. Estoy citando de este artículo, me pareció útil. http://java.dzone.com/articles/just-time-compiler-jit-hotspot
El compilador JIT solo compila el código byte a un código nativo equivalente en la primera ejecución. Tras cada ejecución sucesiva, la JVM simplemente utiliza el código nativo ya compilado para optimizar el rendimiento.
Sin el compilador JIT, el intérprete de JVM traduce el código de byte línea por línea para que parezca que se está ejecutando una aplicación nativa.
JIT se refiere al motor de ejecución en algunas de las implementaciones de JVM, una que es más rápida pero que requiere más memoria, es un compilador justo a tiempo. En este esquema, los códigos de bytes de un método se compilan en un código de máquina nativo la primera vez que se invoca el método. El código de máquina nativo para el método se almacena en caché, por lo que se puede reutilizar la próxima vez que se invoque el mismo método.
JIT significa Just-in-Time, lo que significa que el código se compila cuando es necesario, no antes del tiempo de ejecución.
Esto es beneficioso porque el compilador puede generar código optimizado para su máquina en particular. Un compilador estático, como su compilador de C promedio, compilará todo el código en un código ejecutable en la máquina del desarrollador. Por lo tanto, el compilador realizará optimizaciones basadas en algunas suposiciones. Puede compilar más lentamente y hacer más optimizaciones porque no está ralentizando la ejecución del programa para el usuario.
JIT: justo a tiempo, la palabra en sí misma dice cuándo es necesaria (a pedido)
Escenario típico:
El código fuente se convierte completamente en código máquina.
Escenario JIT:
El código fuente se convertirá en lenguaje ensamblador como estructura [para ex IL (lenguaje intermedio) para C #, ByteCode para java].
El código intermedio se convierte a lenguaje de máquina solo cuando la aplicación necesita que los códigos necesarios solo se conviertan a código de máquina.
Comparación de JIT vs No-JIT:
En JIT, no todo el código se convierte en código de máquina primero, una parte del código que es necesario se convertirá en código de máquina y luego, si un método o funcionalidad llamada no está en la máquina, se convertirá en código de máquina ... se reduce carga en la CPU.
Como el código de la máquina se generará en el tiempo de ejecución ... el compilador JIT producirá un código de máquina que está optimizado para ejecutar la arquitectura de la CPU de la máquina.
Ejemplos de JIT:
- En Java, JIT está en JVM (Java Virtual Machine).
- En C # está en CLR (Common Language Runtime)
- En Android se encuentra en DVM (Dalvik Virtual Machine), o ART (Android RunTime) en versiones más recientes.
JVM en realidad realiza pasos de compilación durante el tiempo de ejecución por razones de rendimiento. Esto significa que Java no tiene una separación de ejecución de compilación limpia. Primero realiza una llamada compilación estática desde el código fuente de Java hasta el código de bytes. Luego, este código de bytes se pasa a la JVM para su ejecución. Pero la ejecución del bytecode es lenta, por lo que la JVM mide la frecuencia con la que se ejecuta el bytecode y cuando detecta un "hotspot" del código que se ejecuta con mucha frecuencia, realiza una compilación dinámica desde el bytecode al código del código "hotspot" (hotspot profiler). Así que, efectivamente, los programas Java de hoy se ejecutan mediante la ejecución de código de máquina.
Jit significa justo a tiempo compilador jit es un programa que convierte el código de bytes de java en instrucciones que pueden enviarse directamente al procesador.
El uso del compilador java justo a tiempo (en realidad, un segundo compilador) en la plataforma del sistema en particular, cumple el código de bytes en un código del sistema en particular, una vez que el compilador jit ha vuelto a compilar el código, generalmente se ejecutará más rápidamente en la computadora.
El compilador justo a tiempo viene con la máquina virtual y se usa opcionalmente. Compila el bytecode en un código ejecutable específico de la plataforma que se ejecuta inmediatamente.
La compilación Just-In-Time (JIT), (también traducción dinámica o compilación en tiempo de ejecución ), es una forma de ejecutar código de computadora que involucra la compilación durante la ejecución de un programa, en tiempo de ejecución, en lugar de antes de la ejecución .
La compilación de TI es una combinación de los dos enfoques tradicionales de traducción a código de máquina (compilación anticipada (AOT) e interpretación ) y combina algunas ventajas e inconvenientes de ambos. La compilación JIT combina la velocidad del código compilado con la flexibilidad de interpretación .
Consideremos JIT utilizado en JVM,
Por ejemplo, los compiladores JVM JIT de HotSpot generan optimizaciones dinámicas. En otras palabras, toman decisiones de optimización mientras la aplicación Java se está ejecutando y generan instrucciones de máquina nativas de alto rendimiento orientadas a la arquitectura del sistema subyacente.
Cuando se elige un método para compilar, la JVM alimenta su código de bytes al compilador Just-In-Time (JIT). El JIT debe comprender la semántica y la sintaxis del código de bytes antes de poder compilar el método correctamente. Para ayudar al compilador JIT a analizar el método, su código de bytes se reformula primero en una representación interna llamada árboles de rastreo, que se asemeja más al código de máquina que al código de bytes. Luego se realizan análisis y optimizaciones en los árboles del método. Al final, los árboles se traducen en código nativo.
Un árbol de seguimiento es una estructura de datos que se utiliza en la compilación en tiempo de ejecución del código de programación. Los árboles de seguimiento se utilizan en un tipo de ''compilador justo a tiempo'' que rastrea el código que se ejecuta durante los puntos de acceso y lo compila. Consulte this .
Referir:
Los siguientes ejemplos de código muestran cómo el JIT optimiza el código Java.
Código antes de la optimización
class A {
B b;
public void newMethod() {
y = b.get();
...do stuff...
z = b.get();
sum = y + z;
}
}
class B {
int value;
final int get() {
return value;
}
}
Código después de la optimización
class A {
B b;
public void newMethod() {
y = b.value;
...do stuff...
sum = y + y;
}
}
class B {
int value;
final int get() {
return value;
}
}
Originalmente, el código contenía dos llamadas al método b.get (). Después de la optimización, las dos llamadas de método se optimizan en una sola operación de copia de variable; es decir, el código optimizado no necesita realizar una llamada de método para adquirir el valor de campo de la clase B.
Sé que este es un hilo antiguo, pero la optimización del tiempo de ejecución es otra parte importante de la compilación JIT que no parece ser discutida aquí. Básicamente, el compilador JIT puede monitorear el programa mientras se ejecuta para determinar formas de mejorar la ejecución. Luego, puede hacer esos cambios sobre la marcha, durante el tiempo de ejecución. Optimización de Google JIT (javaworld tiene un artículo bastante bueno al respecto ) .
Un compilador JIT se ejecuta después de que el programa se haya iniciado y compila el código (generalmente bytecode o algún tipo de instrucciones de VM) sobre la marcha (o justo a tiempo, como se llama) en una forma que suele ser más rápida, típicamente la CPU nativa del host conjunto de instrucciones. Un JIT tiene acceso a información dinámica en tiempo de ejecución, mientras que un compilador estándar no lo hace y puede realizar mejores optimizaciones, como las funciones de alineación que se usan con frecuencia.
Esto contrasta con un compilador tradicional que compila todo el código en lenguaje de máquina antes de que el programa se ejecute por primera vez.
Parafraseando, los compiladores convencionales construyen todo el programa como un archivo EXE ANTES de la primera vez que lo ejecutas. Para los programas de estilo más nuevos, se genera un ensamblaje con pseudocódigo (código p). Solo DESPUÉS de ejecutar el programa en el sistema operativo (p. Ej., Al hacer doble clic en su icono), el compilador (JIT) activará y generará un código de máquina (código m) que el procesador basado en Intel o lo que sea que entienda.
Un compilador justo a tiempo (JIT) es una pieza de software que recibe una entrada no ejecutable y devuelve el código de máquina apropiado para ser ejecutado. Por ejemplo:
Intermediate representation JIT Native machine code for the current CPU architecture
Java bytecode ---> machine code
Javascript (run with V8) ---> machine code
La consecuencia de esto es que, para una cierta arquitectura de CPU, se debe instalar el compilador JIT adecuado.
Compilador de diferencia, intérprete y JIT
Aunque puede haber excepciones en general cuando queremos transformar el código fuente en código de máquina, podemos usar:
- Compilador : toma el código fuente y devuelve un ejecutable
- Intérprete : Ejecuta la instrucción del programa por instrucción. Toma un segmento ejecutable del código fuente y convierte ese segmento en instrucciones de la máquina. Este proceso se repite hasta que todo el código fuente se transforma en instrucciones de la máquina y se ejecuta.
- JIT : Son posibles muchas implementaciones diferentes de un JIT, sin embargo, un JIT suele ser una combinación de un compilador y un intérprete. El JIT primero convierte los datos intermedios (por ejemplo, bytecode Java) que recibe en lenguaje de máquina a través de la interpretación. Un JIT a menudo puede detectar cuándo una cierta parte del código se ejecuta a menudo y compilará esta parte para una ejecución más rápida.
Un compilador que no sea JIT toma el código fuente y lo transforma en un código de bytes específico de la máquina en el momento de la compilación. Un compilador JIT toma el código de bytes independiente de la máquina que se generó en el momento de la compilación y lo transforma en un código de bytes específico de la máquina en el tiempo de ejecución. El compilador JIT que utiliza Java es lo que permite que un único binario se ejecute en una multitud de plataformas sin modificaciones.
Una vez que el compilador de Java ha generado el código de bytes (que es de arquitectura neutral), la ejecución se realizará mediante la JVM (en Java). El cargador cargará el código de bytes en la JVM y luego se interpretará cada instrucción de bytes.
Cuando necesitamos llamar a un método varias veces, necesitamos interpretar el mismo código muchas veces y esto puede llevar más tiempo del necesario. Así que tenemos los compiladores JIT (just-in-time). Cuando el byte se ha cargado en JVM (su tiempo de ejecución), el código completo se compilará en lugar de interpretarse, lo que ahorrará tiempo.
Los compiladores JIT funcionan solo durante el tiempo de ejecución, por lo que no tenemos ninguna salida binaria.
Usted tiene un código que se complementa en algún IL (lenguaje intermedio). Cuando ejecutas tu programa, la computadora no entiende este código. Solo entiende el código nativo. Así que el compilador JIT compila su IL en código nativo sobre la marcha. Lo hace a nivel de método.
Just In Time Compiler (JIT):
Compila los códigos de bytes de Java en las instrucciones de la máquina de esa CPU específica.
Por ejemplo, si tenemos una declaración de bucle en nuestro código java:
while(i<10){
// ...
a=a+i;
// ...
}
El código de bucle anterior se ejecuta 10 veces si el valor de i es 0.
No es necesario compilar el código de bytes 10 veces una y otra vez, ya que la misma instrucción se ejecutará 10 veces. En ese caso, es necesario compilar ese código solo una vez y el valor se puede cambiar por el número de veces requerido. Por lo tanto, el compilador Just In Time (JIT) realiza un seguimiento de dichas declaraciones y métodos (como se dijo anteriormente) y recopila dichos códigos de bytes en el código de la máquina para un mejor rendimiento.
Otro ejemplo similar es que la búsqueda de un patrón usando "Expresión regular" en una lista de cadenas / oraciones.
JIT Compiler no compila todo el código a código de máquina. Compila código que tiene un patrón similar en tiempo de ejecución.
Consulte esta documentación de Oracle en Understand JIT para leer más.