編譯器、直譯器、JIT 的差異:比較執行方式

執行原始碼的方式主要有三種。編譯器(預先編譯,AOT)在程式執行前,把整個程式轉換成機器碼。直譯器不產生機器碼檔案,而是一邊執行一邊讀取程式並運作。JIT 編譯器(即時編譯)先以直譯器開始,再於程式執行中,把經常使用的部分編譯成機器碼。許多語言會組合運用這些方式。

項目編譯器(AOT)直譯器JIT 編譯器
轉換時機執行前。整個程式變成機器碼執行中。一邊讀取程式,一步一步地執行執行中。把經常使用的程式碼編譯成機器碼
啟動啟動快(但需要先建置)啟動快。不需要建置一開始慢。直到程式碼熱起來(暖機)為止
執行速度最快,且容易預測最慢。常比編譯後的程式碼慢好幾倍暖機後接近編譯後的速度,利用執行時的資訊,有時還會更快
可攜性每個平台都需要二進位檔容易移植。只要有直譯器的地方就能執行可攜的位元組碼,加上各平台的執行環境
錯誤偵測許多錯誤能在編譯時發現有問題的那一行被執行時才會出錯依語言而異
記憶體使用量執行時的負擔小直譯器本身會常駐於記憶體為了編譯器與已編譯程式碼的快取,需要額外的記憶體
開發流程編輯、建置、執行編輯後立即執行多半是編輯後執行,或建置成位元組碼
代表性語言C、C++、Rust、Go傳統的 Python(CPython)、Ruby、shell 腳本Java(HotSpot)、JavaScript(V8)、C#(.NET)、PyPy

數值為具代表性的大致參考值,會因世代或產品而異。

適用於什麼情況

編譯器
效能、體積小、行為容易預測很重要時。作業系統、遊戲、嵌入式韌體等。
直譯器
快速實驗、腳本、學習等,開發的速度比執行速度更重要時。
JIT
在可攜的平台上,長時間執行的程式需要速度時。網頁瀏覽器或伺服器應用程式等。

常見問題

Python 是編譯型還是直譯型?

標準實作的 CPython 會把原始碼編譯成位元組碼,再以直譯器執行。PyPy 等其他實作則加入 JIT 編譯器,使其更快。

Java 是編譯型還是直譯型?

兩者皆是。Java 會事先編譯成位元組碼,再由 JVM 在程式執行中以直譯器執行,或以 JIT 編譯成機器碼。

為什麼編譯後的程式碼比較快?

因為整個程式在執行前就已轉換成最佳化的機器碼,執行時不需要再解譯。

JIT 編譯器的暖機是什麼?

一開始以直譯器執行程式,找出經常執行的程式碼後,JIT 才進行編譯。在此之前速度較低。

理解度檢測

關於編譯器與直譯器的差異,下列何者正確?

  1. A編譯器在執行前翻譯,直譯器則是邊讀取邊執行
  2. B編譯器邊執行邊逐行翻譯,直譯器則是在執行前一併翻譯
  3. C編譯器只處理數值計算,直譯器只處理文字的處理
查看答案與解析

正確答案:A. 編譯器在執行前翻譯,直譯器則是邊讀取邊執行

編譯器會在執行前將整個程式翻譯成機器碼等,然後執行翻譯後的結果。雖然翻譯需要花時間,但執行會比較快,也可以花時間進行最佳化。直譯器則是邊讀取程式邊解釋並執行,雖然能馬上試跑,但執行往往較慢。實際上,也常使用結合兩者的方式,例如先翻譯成位元組碼再解釋,並對經常使用的部分進行JIT編譯。並不是依可處理的運算種類來區分。

關於使用JIT編譯的執行環境之特徵,下列何者正確?

  1. A在執行程式之前,先全部翻譯成機器碼再發布
  2. B在執行中將經常使用的部分轉為機器碼,且能利用執行期的資訊
  3. C完全不使用機器碼,永遠逐條指令地解釋位元組碼
查看答案與解析

正確答案:B. 在執行中將經常使用的部分轉為機器碼,且能利用執行期的資訊

在JIT編譯中,一開始是邊解釋位元組碼邊執行,一旦找到被反覆執行的部分(熱點,hotspot),就在執行中把那裡編譯成機器碼。可以利用實際通過的分支與傳入的型別等執行期資訊,進行事前編譯難以做到的大膽最佳化。若假設落空,也具備退回解釋執行的機制。事先全部翻譯的是事前(AOT)編譯,只持續解釋的則是純粹的直譯器。

編譯器內部使用不依賴來源語言、也不依賴CPU的中介表示(IR),其主要優點為何?

  1. A因為使用中介表示後,不必讀取原始碼就能進行編譯
  2. B因為中介表示可由CPU直接執行,所以不需要產生機器碼
  3. C因為可以將各語言專屬的前端與各CPU專屬的後端分開,且最佳化也能共用
查看答案與解析

正確答案:C. 因為可以將各語言專屬的前端與各CPU專屬的後端分開,且最佳化也能共用

要支援M種語言與N種CPU時,若依每種組合各做一個編譯器就需要M×N個,但若透過共用的中介表示,只需要M個從語言到中介表示的前端(frontend),以及N個從中介表示到CPU的後端(backend)。多數最佳化只要在中介表示上做一次,所有語言與CPU都能使用。中介表示並非CPU可直接執行的東西,最後仍需轉換為機器碼。

  1. 關於編譯器詞法分析的作用,下列何者正確?
  2. 關於編譯器的語法分析所進行的工作,下列何者正確?

前往編譯器的練習題

相關名詞的解說

JIT編譯(即時編譯)
在程式執行中,將經常執行的部分編譯成機器碼的方式。可進行利用執行時資訊的最佳化。用於Java與JavaScript的執行環境等。

相關的比較