La risposta di Keno è azzeccata, ma forse potrei dare un po 'più di dettagli su cosa sta succedendo e su cosa intendiamo fare al riguardo.
Attualmente c'è solo una modalità JIT LLVM:
- C'è un interprete molto banale per alcuni semplici dichiarazioni di alto livello.
- Tutti gli altri codici vengono inseriti nel codice macchina prima dell'esecuzione. Il codice è specializzato in modo aggressivo utilizzando i tipi di runtime dei valori a cui viene applicato il codice, propagati attraverso il programma utilizzando l'inferenza di tipo dinamica.
Questo è come Julia ottiene buone prestazioni anche quando il codice viene scritto senza annotazioni di tipo: se si chiama f(1)
si ottiene il codice specializzato per Int64
- il tipo di 1
sui sistemi a 64 bit; se chiami f(1.0)
, ottieni una versione appena provata specializzata per Float64
- il tipo di 1.0
su tutti i sistemi. Poiché ogni versione compilata della funzione sa quali tipi otterrà, può funzionare alla velocità di tipo C. Puoi sabotare questo problema scrivendo e usando funzioni "type-unstable" il cui tipo di ritorno dipende dai dati di runtime, piuttosto che solo i tipi, ma abbiamo fatto molta attenzione a non farlo nella progettazione della lingua principale e della libreria standard.
La maggior parte di Julia è scritta in sé, quindi analizzata, derivata dal tipo e jitted, quindi l'avvio automatico dell'intero sistema richiede circa 15-20 secondi. Per renderlo più veloce, abbiamo un sistema a fasi in cui analizziamo, digitiamo inferenza e quindi memorizziamo nella cache una versione serializzata dell'AST derivato dal tipo nel file sys.ji
. Questo file viene quindi caricato e utilizzato per eseguire il sistema quando si esegue julia
. Nessun codice LLVM o codice macchina è memorizzato nella cache in sys.ji
, tuttavia, per cui è necessario eseguire tutte le operazioni LLVM ogni volta che viene avviato julia
, che pertanto richiede circa 2 secondi.
Questo ritardo di avvio di 2 secondi è piuttosto fastidioso e abbiamo un piano per risolverlo. Il piano di base è quello di essere in grado di compilare interi programmi Julia in binari: o eseguibili eseguibili o .so
/.dylib
librerie condivise che possono essere chiamate da altri programmi come se fossero semplicemente librerie C condivise. Il tempo di avvio di un binario sarà come qualsiasi altro programma C, quindi il ritardo di avvio di 2 secondi svanirà.
Addendum 1: Da novembre 2013, la versione di sviluppo di Julia non ha più un ritardo di avvio di 2 secondi poiché precompila la libreria standard come codice binario. Il tempo di avvio è ancora 10 volte più lento di Python e Ruby, quindi c'è spazio per miglioramenti, ma è piuttosto veloce. Il prossimo passo sarà quello di consentire la precompilazione di pacchetti e script in modo che possano essere avviati alla stessa velocità di Julia stessa.
Addendum 2: Da giugno 2015, la versione di sviluppo di Julia precompila automaticamente molti pacchetti, consentendo loro di caricarsi rapidamente. Il prossimo passo è la compilazione statica di interi programmi Julia.
Questo è stato implementato in Julia Nightly e sarà incluso nella versione 0.3. Il tempo di avvio è notevolmente migliorato. –