簡介
通常,程式有兩種運行方式:靜態編譯與動態解釋。靜態編譯的程式在執行前全部被翻譯為機器碼,而解釋執行的則是一句一句邊運行邊翻譯。
即時編譯器則混合了這二者,一句一句編譯原始碼,但是會將翻譯過的代碼快取起來以降低性能損耗。相對於靜態編譯代碼,即時編譯的代碼可以處理延遲綁定並增強安全性。
類型
即時編譯器有兩種類型,一是位元組碼翻譯,二是動態編譯翻譯。
微軟的.NET Framework,還有絕大多數的Java實現,都依賴即時編譯以提供高速的代碼執行。Mozilla Firefox使用的JavaScript引擎SpiderMonkey也用到了JIT的技術。Ruby的第三方實現Rubinius和Python的第三方實現PyPy也都通過JIT來明顯改善了解釋器的性能。
動態編譯
動態編譯是某些程式語言在執行時用來增進效能的方法。儘管這技術源於Self,但使用此技術最為人所知的是Java。此技術可以做到一些只在執行時才能完成的最佳化。使用動態編譯的執行環境一開始執行速度較慢,之後,完成大部分的編譯和再編譯後,會執行得比非動態編譯程式快很多。因為初始化時的效能延遲,動態編譯不適用於一些情況。在許多實作中,一些可以在編譯時期做的最佳化被延到執行時期才編譯,導致不必要的效能降低。即時編譯是一種動態編譯的形式。
一個非常近似的技術是 遞增式編譯。遞增式編譯器用於POP-2、POP-11、一些Lisp的版本,如Maclisp和最少一種版本的ML語言(PoplogML)。這需要程式語言的編譯器成為執行環境的一部分作為要件以實作。如此便得以在任何時候從終端、從檔案、或從執行中程式所建造數據結構中讀取源碼。然後,轉成機器碼區塊或函式(有可能取代之前同名的函式),之後可立即被程式使用。因為執行中對互動開發和測試的速度的要求,編譯後的機器碼所做的最佳化程度不如標準“批次編譯器”。然而,遞增式編譯過的程式跑起來通常比同一個程式的一般解譯版本還快。遞增式編譯因而能夠同時提供編譯和解譯語言優點。 為了增加可移植性,遞增式編譯通常采兩步驟。第一個步驟會編譯到中間、與平台獨立的語言,然後再到機器碼。在這個例子中,移植只須改變“後端”編譯器。不同於動態編譯,遞增式編譯在程式執行後不會做更進一步的最佳化。
編譯器
編譯器(compiler),是一種電腦程式,它會將用某種程式語言寫成的原始碼(原始語言),轉換成另一種程式語言(目標語言)。
它主要的目的是將便於人編寫、閱讀、維護的高級計算機語言所寫作的原始碼程式,翻譯為計算機能解讀、運行的低階機器語言的程式,也就是執行檔。編譯器將原始程式(source program)作為輸入,翻譯產生使用目標語言(target language)的等價程式。原始碼一般為高級語言(High-level language),如Pascal、C、C++、C# 、Java等,而目標語言則是彙編語言或目標機器的目標代碼(Object code),有時也稱作機器代碼(Machine code)。
一個現代編譯器的主要工作流程如下:
原始碼(source code)→預處理器(preprocessor)→編譯器(compiler)→彙編程式(assembler)→目標代碼(object code)→連結器(Linker)→執行檔(executables), 最後打包好的檔案就可以給計算機去判讀運行了。