La respuesta de Keno es acertada, pero tal vez pueda dar un poco más de detalles sobre lo que está sucediendo y lo que estamos planeando hacer al respecto.
Actualmente sólo hay un modo JIT LLVM:
- Hay un intérprete muy trivial para algunos simples declaraciones de alto nivel.
- Todos los demás códigos se jodieron en el código de máquina antes de la ejecución. El código se especializa agresivamente utilizando los tipos de tiempo de ejecución de los valores a los que se aplica el código, propagados a través del programa mediante la inferencia de tipo dinámico.
Así es como Julia recibe un buen rendimiento incluso cuando el código se escribe sin anotaciones de tipo: si se llama f(1)
tienen el código especializado para Int64
- el tipo de 1
en sistemas de 64 bits; si llama al f(1.0)
, obtiene una versión recién jedizada que está especializada en Float64
- el tipo de 1.0
en todos los sistemas. Como cada versión compilada de la función sabe qué tipos obtendrá, puede ejecutarse a velocidad C-like. Puede sabotear esto escribiendo y usando funciones "tipo inestables" cuyo tipo de devolución depende de datos en tiempo de ejecución, en lugar de solo tipos, pero hemos tenido mucho cuidado de no hacerlo al diseñar el lenguaje central y la biblioteca estándar.
La mayor parte de Julia está escrita en sí misma, luego analizada, de tipo inferida y jitted, por lo que iniciar todo el sistema desde cero lleva unos 15-20 segundos. Para que sea más rápido, tenemos un sistema por etapas donde analizamos, escribimos y deducimos, y luego almacenamos en caché una versión serializada de AST inferida por tipo en el archivo sys.ji
. Este archivo se carga y se usa para ejecutar el sistema cuando ejecuta julia
. Sin embargo, ningún código LLVM o código de máquina está almacenado en la memoria caché en sys.ji
, por lo que toda la configuración de LLVM aún debe realizarse cada vez que se inicia julia
, lo que demora aproximadamente 2 segundos.
Este retraso de inicio de 2 segundos es bastante molesto y tenemos un plan para solucionarlo. El plan básico es poder compilar programas enteros de Julia en binarios: ejecutables que se pueden ejecutar o .so
/.dylib
bibliotecas compartidas que se pueden llamar desde otros programas como si fueran simplemente bibliotecas C compartidas. El tiempo de inicio de un binario será como cualquier otro programa C, por lo que el retraso de inicio de 2 segundos desaparecerá.
Addendum 1: Desde noviembre de 2013, la versión de desarrollo de Julia ya no tiene un retraso de inicio de 2 segundos ya que precompila la biblioteca estándar como código binario. El tiempo de inicio sigue siendo 10 veces más lento que Python y Ruby, por lo que hay margen de mejora, pero es bastante rápido. El siguiente paso será permitir la precompilación de paquetes y scripts para que estos puedan iniciarse tan rápido como lo hace Julia.
Addendum 2: Desde junio de 2015, la versión de desarrollo de Julia precompila muchos paquetes automáticamente, lo que les permite cargarlos rápidamente. El siguiente paso es la compilación estática de todos los programas de Julia.
Esto se ha implementado en los camisones de Julia y se incluirá en la versión 0.3. El tiempo de inicio ha mejorado enormemente. –