Toda esta compilación de “interpretar” o “JIT” / “AOT” es un poco gris. Hay muy pocos escenarios de “solo el uno y no el otro”, y mucha superposición. Y dependiendo de cuán “correcto” desee ser, incluso la CPU “interpreta” el ejecutable binario compilado a través de GCC a partir del código fuente escrito en C De manera similar, cuando la mayoría de los intérpretes leen el archivo de texto, tienden a analizarlo en otra forma y lo almacenan en la RAM que luego “interpretan”; este paso en sí mismo podría clasificarse igualmente como “compilación”, ya que se traduce de un idioma a otro . Por lo tanto, hablar sobre estas ideas X vs Y vs Z puede tener poco significado, dependiendo de su punto de vista o requisitos.
Suponiendo que desea la diferencia entre un intérprete de script (como el corredor de script de archivo BAT en DOS / Windows) y un JIT (como en JVM en el entorno Java Runtime):
Teóricamente es solo una situación de JIT “cambiando” la fuente en instrucciones de CPU nativas cuando se ejecuta e interpreta usando la fuente para llamar a porciones de instrucciones ya nativas. En ambos casos, la fuente se lee y analiza para que el intérprete la “comprenda”, al menos una vez. Sin embargo, JIT puede renunciar a esta etapa de análisis una segunda o tercera vez y luego no necesita llamar a otras partes precompiladas, sino que simplemente envía la parte del código en RAM directamente a la CPU.
- ¿Cómo se puede dividir una secuencia de enteros 'n' en particiones contiguas y no vacías 'm' de manera eficiente de modo que la suma de los máximos de todas las particiones 'm' sea mínima (m <n)?
- Escriba una función recursiva para llenar una matriz MXN con valores de 1 a M * N en el patrón ESPIRAL (debería funcionar para cualquier M> = 0 y cualquier N> = 0).
- Cómo resolver la siguiente pregunta en Java: tengo dos listas vinculadas, que representan dos números: l1: 2-> 3-> 4, l2: 7-> 8; agregue estos dos números y almacene el resultado en l1, es decir, l1 debería convertirse en l1: 3-> 1-> 2
- ¿Cómo diseñarías un sistema grande como Facebook?
- ¿Cuáles son las preguntas que se hacen en las entrevistas con desarrolladores PLSQL para personas con experiencia?
Sin embargo, la compilación (es decir, traducir de una fuente a otra, por ejemplo, códigos de bytes JVM en códigos de bits de CPU) lleva tiempo además de la fase de análisis. Entonces, para la primera ejecución, un intérprete tiene la capacidad de ejecutar el código más rápido. Pero en la próxima llamada de esa misma porción, el JIT tiene la ventaja, ya que luego omite tanto el análisis como la compilación: simplemente ejecuta el código como si normalmente se compilara antes de tiempo.
Nota al margen 1: La mayoría de los intérpretes “traducen” (sinónimo de compilación) la fuente en una fase de lectura / análisis en alguna estructura de memoria (generalmente algo así como un AST – Árbol de sintaxis abstracta). Esto es para que no necesite volver a leer el código cada vez que ejecuta una línea en particular. En efecto, este es un lenguaje intermedio, por lo que podría verse como un “JIT” en el sentido de que “compila” todo el código fuente cuando lo analiza, justo antes de que realmente lo ejecute. Hay algunos intérpretes que no hacen esto, por ejemplo, un intérprete de archivos BAT simplemente lee el archivo BAT y luego envía esos comandos (uno a la vez) a la consola para llamar a esos programas, la consola los interpreta desde cero cada vez, incluso cuando llamando al mismo programa una y otra vez. Es decir, está más cerca de ser un archivo que contiene las pulsaciones de teclas que el usuario habría escrito en la línea de comandos de la consola.
Nota al margen 2: JIT es un poco inapropiado. La mayoría (si no todos) los compiladores “JIT” son de hecho ODC (compiladores bajo demanda). No leen previamente la fuente y la compilan antes de que se ejecute. Eso sería demasiado derrochador y causaría un gran retraso antes de la primera carrera. Por lo tanto, la mayoría comenzaría a ejecutar el código como lo hacen los intérpretes normales, luego lo pasaría al compilador ya que “posiblemente sea necesario compilarlo”. El compilador luego (en su propio tiempo) compilará el código y alterará la versión en memoria de la fuente para que apunte al código compilado. La próxima vez que el intérprete quiera llamar a esa misma sección, verá: “Ah, esto ya está compilado, así que puedo usarlo directamente en lugar de llamar a varias cosas prefabricadas como se especifica en la fuente”. De esta manera, la primera carrera está muy cerca de la misma velocidad que un intérprete normal, por lo que se minimiza el retraso teórico.
Nota al margen 3: Algunos JIT requieren un paso de compilación AOT (Ahead of Time) a un idioma intermedio (generalmente el mencionado en la Nota al margen 1 anterior). Por ejemplo, la fuente Java debe compilarse en códigos de bytes JVM antes de que la JVM pueda “interpretarla”. Esos bytecodes son algo en lo que la etapa de lectura y análisis habría resultado si la JVM fuera un intérprete directo de Java, es decir, lo que almacenaría en su memoria una vez que leyera la fuente. Entonces, en estos, incluso la primera lectura / análisis se minimiza al extremo de simplemente cargarlo en la RAM en lugar de esta traducción en algo “significativo”. Otros (aquellos que pueden cargar directamente el archivo fuente de texto) pueden guardar este “nuevo lenguaje intermedio” analizado en un nuevo archivo para que no sea necesario rehacerlo cuando el programa se ejecuta por segunda vez. Por ejemplo, algunos de los intérpretes de Python guardan esto en un archivo PYC para que pueda cargarlo en lugar de volver a leer y analizar el archivo PY la próxima vez.