学习python的时候一直再想它的原理和优势,却发现我连根本性的问题可能都没考虑清楚。那什么解释型语言?什么是编译型语言?到这个时候才思考这个问题,真是贻笑大方!
为此上网查找,特地回顾学习了两者的区别。
编程语言主要分为:机器语言、汇编语言和高级语言,抽象层次越高越面向于人类,反之越贴近于机器。
一、基本概念
编译型:运行前先由编译器将高级语言代码编译为对应机器的cpu汇编指令集,再由汇编器汇编为目标机器码,生成可执行文件,最后运行生成的可执行文件。最典型的代表语言为C/C++,一般生成的可执行文件及.exe文件。
解释型:在运行时由翻译器将高级语言代码翻译成易于执行的中间代码,并由解释器(例如浏览器、虚拟机)逐一将该中间代码解释成机器码并执行。最典型的代表语言为JavaScript、Python、Ruby和Perl等 。
二、两者异同
两种方式的异同之处:
-
转换为机器码的时机和运行效率 两种转换为机器码的方式,最大不同之处是处理转换为机器码的时机不同。
编译型是在运行前(且只编译一次),需要做转换工作,并生成一个可执行的机器码文件,用户每次运行该可执行文件执行即可,效率、执行速度要比解释型的快。
解释型是在运行时做转换工作,并不生成可执行文件,所以每次运行都需要做一下转换工作,然后再执行,效率自然就低了。
-
纠错排查
编译型语言,在编译阶段即可发现常见的语法或者链接等错误,此机制可在运行前帮助程序员排查出可能潜在的语法、语义和类型转换错误,编译型语言一般都有明确的变量类型检测,也被称作强类型语言,即编译型语言至少能确保所生成的可执行文件肯定是可运行的,至于执行的逻辑不对则属于程序员业务逻辑错误范畴了。
而对于解释型语言,代码中的错误必须直到运行阶段方可发现,由此造成的困惑是:往往一段程序看不出问题但却在运行阶段错误连连且需要一个个排查:变量拼写错误、方法不存在等。但也正是基于解释是在运行期执行转化的特性,一般的解释型语言通常都有自己的shell,可以在不确定某些执行结果是立即“动手执行”试一下,这就比每次都需要编译后才能运行并看到结果省去不少时间,鱼和熊掌不可兼得的理念再一次被验证了。
-
可移植性
编译型在编译后生成的可执行文件,是相对与本机机器指令集的,所生成的可执行文件移植到不同机器指令集的机器上,势必不一定能正常运行。
而解释型的,尽管在不同配置的机器上,也是最终会解释成基于当前机器指令集的机器码并执行,故解释型的可移植性相对来说还是强于编译型的。
-
适用性
从第1点我们知道编译型执行速度较解释型快,因为编译型会把大量时间花在编译上,所以对机器和跨平台性的要求不高,开发操作系统、大型应用程序、数据库程序系统时一般都采用编译型语言.
而解释型由于每次运行都需要解释一遍,对机器有一定的配置要求(在内存较小的机器上去一遍遍解释执行肯定是件很痛苦的事),适用的地方是一些例如网页脚本、服务器脚本及辅助开发接口这类对机器配置要求不高、需要一定跨平台兼容性的程序。
####鱼和熊掌可兼得吗? 综上所述,既然编译型与解释型各有优缺点又相互对立,所以一些语言都有把两者折衷起来的趋势:
Java为了实现跨平台的特性,专门在从高级语言代码转换至机器码过程的中间加入了一层中间层JVM(java虚拟机),Java首先依赖编译器将代码(.java)编译成JVM能识别的字节码文件(.class),然后由JVM解释并执行改字节码,也可结合JIT(just-in-time compilation即时编译)技术,将解释生成的机器码转换为更高效的本地机器码,且该机器码可被缓存,来提高重复执行的效率。这样的结合,令程序员在使用Java时即可享受编译带来的强类型编译检查的好处,又能在执行时享受代码执行的高效性和跨平台性,何乐而不为呢?
Python是解释型语言,但为了效率上的考虑,也提供了编译方式,编译后生成的也是字节码的文件形式,并由Python的的VM(虚拟机)的去执行,这点可以说和Java的编译执行方式类似。不同点在于,Python的编译并非强制执行的操作,确切来说Python的编译是自动的,通常发生在对某个模块(module)的调用过程中,编译成字节码的可以节省加载模块的时间,以此达到提高效率的目的。可见,某些先进的高级语言在对编译和解释方面的拿捏舍去,都采取了一种:两手抓,两手都要硬的态度哦:)。
总之,编译型语言的执行效率高,纠错排查能力强,但是可移植性差。而解释型语言的执行效率较低,但是不必每次编译才能执行,同时可移植性强。这些特点导致它们的适用情形是不相同的。
同时也有“集大成者”,那就是Java和Python。
也可以参考下面几个博文: