2013-04-18 5 views
5

Mentre il benchmarking un'applicazione Clojure e cercando di definire con precisione i problemi di prestazioni, ho notato questo comportamento peculiare: anche quando l'intero programma è scritto in Java, una volta lanciato da Leiningen sembra sperimentare un significativo rallentamento.Perché un programma Java/Clojure rallenta quando viene eseguito da Leiningen?

Dire che ho questo programma Java:

public class Foo { 
    public static void main(String[] args) throws Exception { 
     for (int i = 0; i < 10; i++) 
      run(); 
    } 

    public static void run() { 
     final long start = System.nanoTime(); 

     Random r = new Random(); 
     double x = 0; 
     for(int i=0; i<50000000; i++) 
      x += r.nextDouble(); 

     final long time = TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS); 
     System.out.println("time (ms): " + time + " total: " + x); 
    } 
} 

Quando ho semplicemente eseguire il programma, ottengo tempi di esecuzione (per run) di circa 1s. Tuttavia, quando l'eseguo da Leiningen in questo modo: volte

lein run -m Foo 

vengo percorso di circa 2s! In che modo Clojure/Leiningen riesce a rallentare un programma Java completo di così tanto? Che cosa sto facendo di sbagliato?

Ho provato esaminando le proprietà del sistema in entrambe le manche e non ho trovato nulla abbagliante (come diverse impostazioni JIT). In entrambi i casi uso Java 7 con il compilatore del server.

EDIT: Non so il motivo per cui la questione è stata downvoted. Non sono contro Clojure. Al contrario, amo Clojure e lo userò. Ho solo questo grave problema di prestazioni che devo assolutamente risolvere.

UPDATE: Esecuzione lein trampoline risolve il problema! (anche se non ho idea del perché) Ho aggiornato la domanda per riflettere che questo è davvero un problema di Leiningen, non un problema di Clojure.

altro aggiornamento: Questo accade per qualsiasi codice Clojure pure. Correre senza trampolino rallenta il codice fino a 5 volte.

+0

Suggerimento: 'lein aiuto trampoline' – noahlz

risposta

-1

leiningen richiede circa un secondo per iniziare.

+0

Ovviamente, non sto contando i tempi di avvio del Lein. Guarda il programma. Sto osservando i tempi nel metodo di esecuzione. – pron

+0

Hai ragione. Immagino ci sia qualcosa di strano in corso lì. Sei sicuro di avere le stesse cose sul classpath? –

+0

Inoltre: potresti avere limiti di memoria diversi, quindi il programma avviato da lein potrebbe dover eseguire più operazioni di garbage collection. Il problema è difficile da diagnosticare senza le esatte impostazioni/proprietà del sistema. –

1

Probabilmente è dovuto a un comportamento JIT diverso.

Le prestazioni di JIT compilato può essere influenzata da una serie di cose, tra cui:

  • Cosa codice di avvio viene chiamato, che interesserà le statistiche JIT
  • Quali altre classi sono stati caricati (ad esempio altre sottoclassi di Random) che potrebbero influenzare l'ottimizzazione del compilatore di chiamata di metodo spedizione
+0

Ho provato entrambi con -XX: + PrintCompilation. In entrambi i casi viene eseguito run() (l'unica funzione interessante qui). Vedi l'aggiornamento, però. In qualche modo, è leiningen a causare questo. – pron