La compilación dinámica es un proceso que utilizan algunas implementaciones de lenguajes de programación para ganar rendimiento durante la ejecución del programa. Aunque la técnica se originó en Smalltalk , [1] el lenguaje más conocido que utiliza esta técnica es Java . Dado que el código de máquina emitido por un compilador dinámico se construye y optimiza en tiempo de ejecución del programa, el uso de la compilación dinámica permite optimizaciones para la eficiencia que no están disponibles para los programas compilados estáticamente (es decir, aquellos compilados por un llamado "compilador por lotes", como se escribe a continuación) excepto a través de la duplicación de código o metaprogramación .
Los entornos de ejecución que utilizan compilación dinámica suelen hacer que los programas se ejecuten lentamente durante los primeros minutos y, después de eso, se realiza la mayor parte de la compilación y recompilación y se ejecuta rápidamente. Debido a este retraso inicial en el rendimiento, la compilación dinámica no es deseable en ciertos casos. En la mayoría de las implementaciones de compilación dinámica, algunas optimizaciones que podrían realizarse en el momento de la compilación inicial se retrasan hasta la siguiente compilación en el momento de la ejecución , lo que provoca más ralentizaciones innecesarias. La compilación justo a tiempo es una forma de compilación dinámica.
Una técnica estrechamente relacionada es la compilación incremental . Un compilador incremental se utiliza en POP-2 , POP-11 , Forth , algunas versiones de Lisp , por ejemplo Maclisp y al menos una versión de ML ( Poplog ML). Esto requiere que el compilador del lenguaje de programación sea parte del sistema de ejecución. En consecuencia, el código fuente se puede leer en cualquier momento, desde la terminal, desde un archivo o posiblemente desde una estructura de datos construida por el programa en ejecución, y traducirse en un bloque de código de máquina o función (que puede reemplazar una función anterior del mismo nombre), que luego está inmediatamente disponible para su uso por el programa. Debido a la necesidad de velocidad de compilación durante el desarrollo y las pruebas interactivas, es probable que el código compilado no esté tan optimizado como el código producido por un "compilador por lotes" estándar, que lee el código fuente y produce archivos de objetos que posteriormente se pueden vincular y ejecutar. Sin embargo, un programa compilado de forma incremental normalmente se ejecutará mucho más rápido que una versión interpretada del mismo programa. La compilación incremental proporciona así una mezcla de los beneficios de los lenguajes interpretados y compilados. Para facilitar la portabilidad, generalmente es deseable que el compilador incremental funcione en dos etapas: primero compilando en un lenguaje intermedio independiente de la plataforma y luego compilando desde allí al código de máquina para la máquina anfitriona. En este caso, la portabilidad requiere únicamente cambiar el compilador "de back-end". A diferencia de la compilación dinámica, como se definió anteriormente, la compilación incremental no implica optimizaciones adicionales después de que el programa se ejecuta por primera vez.