在这四种语言里有两种不同的程序运行过程:
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