codesun
2016-01-07 14:53:42 +08:00
编译器本质是一种映射程序,编译器从其提供的语法映射到 IR , IR 经过优化可导出汇编或直接经由 codegen 生成本地代码。
先不说别的,虽然二进制只有 0 和 1 ,但是组合爆炸,其次语言的语法不同,生成的下层表示也不同,编译器的处理方式不同,下层的代码也不同,还有最重要的优化器。
一般来说,静态编译语言速度优于解析型,即使后者有 JIT ,也很难超越前者,当然除非前者没有优化器,而且 codegen 很烂,那就另当别论了。
同样是编译型,内部也相差很大,主要取决于语言是不是提供了很多语法糖,是不是由编译器添加了比较多的隐式操作,比如运行时类型检查,运行时数组越界检查,甚至是 GC 等。这些都是开销,比如 C++编译器就会做很多这方面的工作,如 virtual 函数,多态的 vtable ,异常调用等。
对于是否有足够优秀的优化器,这里的内容相当多且复杂,就比如你的编译器支持循环的向量化优化,那么同样的程序,性能就完全不一样了。当然还有很多函数内以函数间的分析与优化,都会对性能产生不同的影响,这方面可以对比 llvm 与 gcc 。
对于编译型语言和解析型语言,差别在于前者生成本地代码,而后者生成解析器可以识别的代码,因此这里涉及从目标代码到本地代码转换的过程,你可以简单地认为解析器就是一个 while+switch 。可能看似性能差别应该不大,但是结果往往是相差一个数量级左右,看你实现地好坏了,或许直接用汇编写个解析器,性能会更好点,应该很少有人会这么做,因为现在大家完全可以用即时编译来弥补一定的性能差距。