在C,C++,java和python執行時直譯器和編譯器的區別

林堯彬發表於2020-04-04

在這四種語言裡有兩種不同的程式執行過程:

1.  高階語言-> 機器程式碼:

C和C++的編譯過程有幾個步驟:

> 預編譯: 將.c 檔案轉化成 .i檔案),使用的gcc命令是:gcc –E,對應於預處理命令cpp

> 編譯: 將.c/.h檔案轉換成.s檔案, 使用的gcc命令是:gcc –S, 對應於編譯命令 cc –S

> 彙編:將.s 檔案轉化成 .o檔案,使用的gcc 命令是:gcc –c,對應於彙編命令是 as

> 連結:將.o檔案轉化成可執行程式,使用的gcc 命令是: gcc,對應於連結命令是 ld

前三步都可以叫做編譯,它的輸出是一條條機器指令,在連結中會把機器指令和目標檔案庫檔案結合起來,生成系統可執行的檔案.exe。

 

2. 高階語言-> 位元組碼 ->機器程式碼:

2.1 java

java 在執行過程中先利用javac將原始檔編譯成.class位元組碼,然後在jvm上繼續解釋和編譯成可執行的機器程式碼。你可能注意到在jvm過程中同時有編譯和解釋的過程,這是跟jvm執行機制有關:

 

在理解這幅圖之前,先了解下JIT的歷史。一開始Sun公司採用classic vm作為JVM,但是飽受“Java比C++慢的多”的詬病。後來Sun公司引入HotSpot作為虛擬機器,並引入JIT(Just In Time)技術。JIT又稱即時編譯器,雖說是編譯器,它跟javac編譯器的功能不同。JVM有三種執行模式:解釋模式,編譯模式,混合模式。上圖對應的是混合模式,其流程為:

1.原始碼經過編譯器成為.class檔案,也就是位元組碼。

2.程式位元組碼經過JIT判斷,是否屬於熱點程式碼,例如迴圈或者頻繁呼叫的方法。

3.如果是,被JIT編譯成機器位元組碼,對應具體硬體處理器(如sparc,intel)。

4.如果不是,被JIT直譯器解釋執行。

5.作業系統和類庫的呼叫。

6.硬體。

所以JIT是一個直譯器和編譯器的集合,某些“熱點程式碼”可以通過編譯來節省逐條解釋的耗時,其他程式碼仍舊通過直譯器執行。這樣的混合模式執行要比純編譯模式快。那麼為什麼純編譯模式要比混合模式慢呢?部落格中給出的回答是:

編譯執行不加篩選的將全部程式碼進行編譯機器碼不論其執行頻率是否有編譯價值,在程式響應時間的限制下,編譯器沒法採用編譯耗時較高的優化技術(因為 JIT的編譯是首次執行或啟動的時候進行的!),所以,在純編譯執行模式下的java程式執行效率跟C/C++也是具有較大差距的。

看來java也不是完全的解釋性語言。

 

2.2 python

python的編譯過程是自動執行的,並不需要人工另外的操作。

py檔案被編譯成.pyc 位元組碼檔案。這個位元組碼檔案跟平臺無關。接下來由pvm解釋執行這個位元組碼檔案,每一次負責將一條位元組碼檔案語句翻譯成cpu可以直接執行的機器程式碼,然後在接下來下一句。

對於python來說,沒有針對機器程式碼的編譯,每一條語句的執行都是直接對原始碼或者中間程式碼進行解釋執行。而少了這個編譯的過程,使得解釋型語言執行較慢。另外,在逐條解釋的過程中,效率也較低。

解釋型語言也有優點,比如它的平臺無關性,另外,具體逐條解釋的時候會進行動態優化,有時不見得比編譯型的慢。

python最開始也有一個編譯的過程,所以跟java一樣,也不是純的解釋性語言。

總結下來,所謂的解釋性語言主要有三種:

1. 直接執行高階程式語言:比如shell內建的直譯器。

2. 將原始碼轉化成一些有效率的位元組碼或者中間程式碼,然後再解釋執行:比如pvm

3. 將原始碼編譯成位元組碼或者中間程式碼,並指示處理器執行編譯後的程式:比如JIT 

 參考博文: 
http://blog.csdn.net/cdh1213/article/details/6919143 
http://www.cnblogs.com/lyhero11/p/5080306.html 
http://developer.51cto.com/art/201503/467055.htm

轉載於:https://www.cnblogs.com/dali133/p/9611008.html

相關文章