2011-05-16 9 views
19

Ho scritto alcune piccole applicazioni di utilità in Clojure che compilo in file JAR eseguibili autonomi ("uberjars") usando Maven e il plugin maven-shade-plugin. Questi uberjars contengono versioni non compresse di clojure.jar e altre librerie (es .: commons-cli) da cui dipende l'applicazione. Sono convenienti perché posso inviarli a un cliente senza richiedere che il cliente installi Clojure (tutti i clienti hanno già installato JRE).Prestazioni di avvio dell'applicazione Clojure

Ho scoperto che le applicazioni Clojure impiegano diversi secondi all'avvio, mentre applicazioni simili scritte in Java iniziano in secondi secondari sulle stesse macchine (ad esempio, il tempo di mostrare un messaggio di utilizzo).

Ho il sospetto che sia perché Clojure è al volo compilando parte del codice nella libreria clojure.core in quanto vi è il codice sorgente (file .clj) nel file clojure.jar.

C'è un modo per precompilare questo codice sorgente? Si può fare qualcos'altro per accelerare le prestazioni di avvio? Ho sentito lamentele da parte dei clienti sulla durata dell'avvio (e non sanno o non si preoccupano che l'applicazione sia scritta in Clojure o Java o Foobar).

+0

Vedere anche http://blog.ndk.io/solving-clojure-boot-time.html e http://dev.clojure.org/display/design/Improving+Clojure+Start+Time – Vadzim

risposta

4

JVM (almeno HotSpot di Oracle) fa cosa molto difficile da ridurre il tempo di avvio. Esso non viene caricato in memoria classi e metodi tutti programma di, carica solo risorse che ha bisogno al momento. Non ci sono così tanti codici necessari per mostrare un messaggio di utilizzo o qualcosa del genere, quindi solo poche funzioni sono effettivamente caricate e il programma Java viene avviato rapidamente.Inoltre, HotSpot non compila nemmeno queste poche funzioni - utilizza la compilazione JIT (e altre ottimizzazioni) per il codice, che viene eseguita ripetutamente.Non c'è motivo di dedicare del tempo a compilare funzioni che verranno eseguite una sola volta, ad esempio quasi tutti i metodi di avvio e HotSpot no.

Quindi, che dire di Clojure? Non penso che ti piacerebbe riscrivere il nucleo di Clojure per aggiungere funzionalità simili. Tuttavia, puoi utilizzare lo stesso approccio all'interno del tuo codice Clojure. Hai detto che le tue utilità utilizzano diverse librerie, che possono rallentare l'avvio. Quindi, carica le librerie pigramente il il più possibile. Ad esempio, è possibile escludere l'opzione :use dalla definizione del proprio spazio dei nomi e richiamare esplicitamente lo use nelle funzioni principali. Questo non ridurrà il tempo totale, ma sarà spostamento dalay al momento, quando non è così apprezzabile. Puoi anche scrivere una piccola parte del tuo programma in Java e chiamare il codice Clojure solo quando è effettivamente necessario.

+0

Salve, la soluzione sopra menzionata porterebbe certamente a miglioramenti delle prestazioni, ma a quale costo? ! La buona notizia è che in Clojure 1.3 c'è una funzione sperimentale (ahimè "temporaneamente disabilitata" come è scritto in un recente commit in github) il cui scopo è abilitare il "lazy loading" dei fns compilati. –

3

Sul sito Clojure c'è una bella descrizione di AOT compilation. Questo eliminerà già alcuni tempi di avvio.

Modifica: ci sono stati alcuni sforzi per eseguire programmi Clojure su una JVM persistente, riducendo così il tempo di avvio. Look-up jark + jvm. Tuttavia, il sito sembra aver disapeared :(

+0

Lo faccio già AOT con il mio codice personale e include solo i file '.class' nel JAR, ma sembra che il clojure.core debba includere un codice sorgente che viene rispettato all'avvio dell'applicazione, a meno che non sia lontano dalla base e che l'avvio lento sia a causa di qualche altra causa. Stavi suggerendo di ricostruire il clojure.jar con AOT? – Ralph

+0

Non preoccuparti, anche se clojure.jar ha alcuni file .clj, ha anche i corrispondenti file .class. L'avvio lento è principalmente dovuto al tempo di avvio di JVM, ogni volta che si esegue l'utilità Clojure. –

+1

"L'avvio lento è dovuto principalmente al tempo di avvio della JVM, ogni volta che si esegue l'utilità Clojure." - se è vero, perché le applicazioni Java iniziano in meno di un secondo (Macbook Pro 2,66 GHz Core i7, 9 GB RAM, OsX 10.6.7)? – Ralph

1

Naturalmente, c'è anche l'argomento JVV java-client per migliorare le prestazioni di avvio di JVM. Questo SO question entra in dettaglio su questo argomento.