實際上,V8是用C++編寫的。然而,與JVM基本上是一樣的,而JVM是用C.V8 JITs編寫的Javascript代碼並執行JIT代碼。同樣,JVM JIT編譯(或熱點編譯)字節碼(不是Java)並執行生成的代碼。
Bytecode不是靜態的,就像Java一樣。事實上它可以是相當動態的。另一方面,Java大多是靜態的,將Java與字節碼混淆是不正確的。 java編譯器將Java源代碼轉換爲字節碼,JVM執行字節碼。欲瞭解更多信息,我建議你看看John Rose的博客(example)。那裏有很多很好的信息。另外,請嘗試通過Cliff Click尋找對話(如)。
同樣,Clojure代碼直接編譯爲字節碼,然後JVM對該字節碼執行相同的過程。編譯Clojure通常在運行時完成,這不是最快的過程。同樣,將Clojurescript翻譯成Javascript也不是很快。 V8的Javascript轉換爲可執行形式顯然是相當快的。雖然Clojure可以提前編譯爲字節碼,並且可以消除大量啓動開銷。
正如你所說,說JVM解釋字節碼也是不正確的。 1.0版本在17年前就已經這樣做了!
傳統上,有兩種編譯模式。第一種模式是JIT(Just in Time)編譯器。字節碼直接轉換爲機器碼。Java的JIT編譯執行速度很快,並且不會生成高度優化的代碼。它運行正常。
第二種模式稱爲熱點編譯器。熱點編譯器非常複雜。它在解釋模式下非常快速地啓動程序,並在程序運行時對其進行分析。當它檢測到熱點(頻繁執行的代碼中的點)時,它會編譯這些熱點。而JIT編譯器必須是快速的,因爲除非被JIT處理,否則什麼都不執行,熱點編譯器可以花費額外的時間來優化它正在編譯的代碼。
此外,它可以返回並重新訪問該代碼,並在必要和可能的情況下對其應用更多優化。這是熱點編譯器可以開始擊敗已編譯的C/C++的關鍵。由於它具有代碼的運行時知識,因此可以應用靜態C/C++編譯器無法完成的優化。例如,它可以內聯虛擬功能。
熱點還有一個其他功能,盡我所知沒有其他環境,它也可以去代碼,如果有必要。例如,如果代碼持續採用單個分支,並且該代碼已經過優化,並且運行時條件發生變化,則代碼會強制其他(未優化的)分支,並且性能突然變得糟糕。熱點可以對該功能進行優化,並再次開始分析以找出如何使其運行得更好。
熱點的缺點是開始有點慢。 Java 7 JVM的一個變化是將JIT編譯器和熱點編譯器結合起來。儘管這種模式是新的,但它並不是默認的,但是一旦初始啓動應該是好的,然後它可以開始JVM擅長的advanced optimizations。
乾杯!
「Java比C慢」可能適用於許多問題領域,但無關緊要。適當的問題是「Java比V8慢」。 V8不會將你的代碼作爲編譯後的C代碼運行,它恰好是用C編寫的JavaScript解釋器。 –
@EricJ。我想這就是我的問題,我看到V8解釋了Clojure生成的JavaScript與解釋Clojure的JVM。 V8將JS編譯成機器代碼並運行它。 JVM做的更快嗎? – lobsterism
Clojure被編譯爲字節碼,就像Java一樣。是什麼讓你覺得它不是? –