In realtà, V8 è scritto in C++. Tuttavia, fa fondamentalmente la stessa cosa della JVM, e JVM è scritto nel codice Javascript JITs di C. V8 ed esegue il codice JIT. Allo stesso modo JIT JIT compila (o compila hotspot) bytecode (NON Java) ed esegue quel codice generato.
Bytecode non è statico, come Java. In effetti può essere abbastanza dinamico. Java, d'altra parte, è per lo più statico e non è corretto confondere Java con il bytecode. Il compilatore java trasforma il codice sorgente Java in bytecode e JVM esegue il bytecode. Per ulteriori informazioni, ti consiglio di guardare il blog di John Rose (example). Ci sono molte buone informazioni lì. Inoltre, prova a cercare i discorsi di Cliff Click (come).
Allo stesso modo, il codice Clojure viene compilato direttamente in bytecode e la JVM esegue quindi lo stesso processo con quel bytecode. Compilare Clojure viene solitamente eseguito in fase di runtime, che non è il processo più veloce. Allo stesso modo, anche la traduzione di Clojurescript in Javascript non è veloce. La traduzione di V8 di Javascript in forma eseguibile è ovviamente abbastanza veloce. Clojure può essere in anticipo compilato in bytecode e ciò può eliminare un sacco di sovraccarico di avvio.
Come hai detto, non è proprio corretto dire che JVM interpreta bytecode. La versione 1.0 lo ha fatto più di 17 anni fa!
Tradizionalmente, c'erano due modalità di compilazione. La prima modalità è un compilatore JIT (Just in Time). Dove bytecode è tradotto direttamente nel codice macchina.La compilazione JIT di Java viene eseguita rapidamente e non genera codice altamente ottimizzato. Funziona OK.
La seconda modalità è denominata il compilatore di hotspot. Il compilatore di hotspot è molto sofisticato. Avvia il programma molto rapidamente in modalità interpretata e lo analizza mentre il programma viene eseguito. Come rileva gli hotspot (punti nel codice che vengono eseguiti frequentemente), li compilerà. Mentre il compilatore JIT deve essere veloce perché nulla viene eseguito a meno che non sia JIT, il compilatore di hotspot può permettersi di dedicare ulteriore tempo per ottimizzare il moccio dal codice che sta compilando.
Inoltre, può tornare indietro e rivisitare quel codice in seguito e applicare ulteriori ottimizzazioni su di esso se necessario e possibile. Questo è il punto in cui il compilatore hotspot può iniziare a battere C/C++ compilato. Poiché ha una conoscenza runtime del codice, può permettersi di applicare le ottimizzazioni che un compilatore C/C++ statico non può fare. Ad esempio, può integrare funzioni virtuali.
Hotspot ha un'altra caratteristica, che in base alle mie conoscenze nessun altro ambiente ha, può anche deoptimizzare il codice se necessario. Ad esempio, se il codice prendesse continuamente un singolo ramo, e ciò fosse ottimizzato e le condizioni di runtime cambiassero forzando il codice verso il basso, l'altro ramo (non ottimizzato) e le prestazioni diventerebbero improvvisamente terribili. L'hotspot può deoptimizzare tale funzione e ricominciare l'analisi per capire come farlo funzionare meglio.
Uno svantaggio di hotspot è che inizia un po 'lento. Una modifica della JVM di Java 7 è stata la combinazione del compilatore JIT e del compilatore di hotspot. Questa modalità è nuova, tuttavia, e non è l'impostazione predefinita, ma una volta avviata l'avvio dovrebbe essere buona e quindi è possibile iniziare la advanced optimizations che la JVM è così buona.
Cheers!
"Java è più lento di C" può essere vero per molti domini problematici, ma è irrilevante. La domanda appropriata è "Java è più lento di V8". V8 non esegue il tuo codice come codice C compilato, è un interprete JavaScript che sembra scritto in C. –
@EricJ. Immagino che questa sia la mia domanda allora, sto vedendo V8 interpretare JavaScript generato da Clojure rispetto a una JVM che interpreta Clojure. V8 compila il JS fino al codice macchina e lo esegue. Che cosa fa la JVM più veloce? – lobsterism
Clojure è compilato in byte code, proprio come Java. Cosa ti ha fatto pensare che non fosse? –