.NET 編譯執行or解釋執行?

鴨脖發表於2012-12-31

 前段時間從網上看到ASP和ASP.NET之間的區別中有這樣一句話“asp是解釋執行,.net是編譯執行”,從網上有深入查了查覺得有些收穫,整理了一下就發上來了。

      計算機並不能直接地接受和執行用高階語言編寫的源程式,源程式在輸入計算機時,通過"翻譯程式"翻譯成機器語言形式的目標程式,計算機才能識別和執行。這種"翻譯"通 常有兩種方式,即編譯方式和解釋方式。

      編譯方式是指利用事先編好的一個稱為編譯程式的機器語言程式,作為系統軟體存放在計算機內,當使用者將高階語言編寫的 源程式輸入計算機後,編譯程式便把源程式整個地翻譯成用機器語言表示的與之等價的目標程式,然後計算機再執行該目標程式,以完成源程式要處理的運算並取得 結果。編譯程式是將所有的內容一次性全部翻譯,再交由計算機執行。如編譯程式一般會生成一個如*.exe,與低階語言等價的可執行程式(低階語言的目標程式,彙編程式),這個可執行程式就是編譯好的目標程式,計算機再執行這個程式,將其整個翻譯成機器語言。

      解釋方式是指源程式進入計算機後,一般是讀一句源程式,翻譯一句,執行一句,不產生目的碼。如PASCALFORTRANCOBOL等高階語言執行編譯方式;BASIC語言則以執行解釋方式為主;而PASCALC語言是能書寫編譯程式的高階程式設計語言。

      編譯程式與解釋程式最大的區別之一在於前者生成目的碼,而後者不生成;此外,前者產生的目的碼的執行速度比解釋程式的執行速度要快;後者人機互動好,適於初學者使用。用COBOLFORTRAN等語言編寫的程式考慮到執行速度一般都是編譯執行。

      一般來說,解釋的速度比編譯慢,編譯是一次性開銷,解釋每次執行都引起額外開銷。

     .NET的編譯勉強算是編譯,但不是傳統意義上的編譯。應該說是個更高階的解釋過程。

      編譯:編好程式選擇生成時,從 原始碼編譯到中間語言(IL),這個中間語言是.NET自已的一種語言格式,雖然它也是 EXE,但它並非直接可以執行的二進位制程式碼,而是一種比原始碼更為緊湊的程式程式碼。 
      解釋:軟體執行的時候,系統會自動載入 .NET Framework 對中間語言形式的 EXE 進行解釋執行。

      它的過程分兩步,首先是原始碼到中間程式碼的“編譯”,這一步嚴格說不是編譯,只是將原始碼翻譯成了中間程式碼,但是形式上像是傳統的編譯-生成了可執行文 件。但是這個可執行檔案並不是真正的可執行檔案,需要.NET框架在你執行它的時候再及時翻譯為CPU機指令,它的改進在於這個及時編譯比傳統的解釋方式效能更好,因為程式中的指令不是每次執行都解釋,而是在 程式首次執行時一次性編譯(解釋),只要程式沒有退出,解釋的過程就不再發生。

      以下是對公共語言執行時(CLR)的一些解釋。

1.2  .NET Framework的架構

現在的計算機程式語言的執行方式分為兩種,一種是編譯執行,一種是解釋執行。編譯執行是指源程式程式碼先由編譯器編譯成可執行的機器碼,然後再執行; 解釋執行是指原始碼程式被直譯器直接讀取執行。編譯執行的程式語言我們常見的有C、C++、VB等,解釋執行的有Python、Java Script、HTML等程式語言。編譯執行和解釋執行各有優缺點,比如我們說編譯執行的語言通常執行效率高,而解釋執行的語言通常可以靈活的跨平臺,下 圖(圖1.3)展現了編譯執行和解釋執行的原理:

 
圖1.3  程式執行原理圖

對於計算機來講它只是一臺機器,它只能認識0101011這樣的二進位制機器指令。編譯執行一次性將高階語言源程式編譯成二進位制的可執行指令。而解釋 執行是由該語言(如HTML)執行環境(如瀏覽器)讀取一條該語言的源程式,然後轉變成二進位制指令交給計算機執行。如果把高階語言原始碼比作一本外文書 籍,那麼編譯執行就是一次性翻譯成中文,然後你再看;而解釋執行就是你拿著個翻譯機,讀一行翻譯一行的看。這裡要注意的是,我們說編譯執行的程式,原始碼 需要一個叫編譯器的裝置編譯成作業系統可執行的機器碼,形式比較統一,而解釋執行就不一樣了,它的形式和方法各異,我們說網頁HTML程式碼它是靠瀏覽器解 釋執行的,而可以在Office中使用的指令碼語言VBScript卻是由Office來負責執行的。

1.2.1  什麼是公共語言執行時(CLR)

當然,上面這些都是比較傳統的程式程式碼執行方式,從Java語言開始,一種新的程式語言執行方式產生了,這就是“中間碼+虛擬機器”執行機制。這種執 行方式,程式語言原始碼需要被編譯成一種特殊的中間碼,這種中間碼是不能直接執行的,它需要一個叫“虛擬機器”的裝置來管理和執行,可以是解釋執行也可以是 編譯執行。因為“虛擬機器”可以參與和管理程式程式碼的執行,因此解決了很多傳統編譯語言一些致命的缺點,如垃圾記憶體回收、安全性檢查等。也是因為如 此,.NET框架也採用了此種語言執行方式,這裡管理和執行中間碼“虛擬機器”在.NET框架中就是公共語言執行時(CLR),它負責管理和執行由.NET 編譯器編譯產生的中間語言程式碼。右圖(圖1.4)展示了.NET程式的執行原理:

 

整個執行過程是這樣的,首先我們在開發環境Visual Studio .NET中編寫C#程式碼,然後這些原始碼被Visual Studio .NET中內建的C#編譯器編譯成中間語言程式碼(中間語言是一種類似於彙編的程式語言,還不是機器碼,我們後面會專門介紹),最後中間語言程式碼由作業系統 中.NET Framework的元件CLR管理和執行。另外,從上圖你也可以看出,公共語言執行時的另外一個作用是可以輕鬆地實現跨平臺。當然,條件是要在作業系統 上安裝.NET Framework,這個跨語言的原理是和Java一樣的,安裝了語言執行時的作業系統就可以識別和執行中間語言程式碼。值得一提的是,雖然微軟自己並不提 倡跨平臺(跨平臺會影響Windows作業系統的市場壟斷),但現在已經出現了在Linux作業系統中執行和編輯.NET程式的平臺,就是Mono平臺。 該平臺包括有C#編譯器、公共語言執行時以及相關的一套.NET類庫。Mono平臺可使開發者開發的.NET應用程式不僅能在Windows上執行,也能 在任何支援Mono的作業系統上執行,包括現有的Linux和UNIX作業系統。

關於公共語言執行時還要注意,. NET裡面的CLR和Java裡面的虛擬機器JVM是不同的,我們說Java的虛擬機器一般是解釋執行的,而CLR是編譯執行,是在應用程式第一次被呼叫時一 次性編譯成機器碼再執行,這樣做的好處一個是儘可能的避免瞭解釋執行所帶來的效率降低的問題;另外可以做到充分利用本機資源,CLR可以針對本地的資源進 行優化編譯,這個特性人們考慮可能在將來會使.NET程式碼的執行效率甚至超過C++,因為C++編譯器是通用的,並沒有照顧到不同計算機本地資源的不同。

相關文章