在這四種語言里有兩種不同的程序運行過程:
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