是什么让Java编译器如此之快?

我想知道是什么让主编译器(sun编译的javac)如此快速地编译?

..以及Microsoft的C#.NET编译器。

我将它们与C ++编译器(如G ++)进行比较,所以也许我的问题应该是C ++编译器太慢了:)


这个问题很好地回答了这个问题:为什么C ++编译需要这么长时间? (正如贾尔夫在评论部分指出的那样)

基本上它是C ++缺少的模块概念,以及编译器所做的积极优化。


我认为最困难的部分不是编译头文件(除非它们真的很大,但在这种情况下可以使用预编译头)。 最糟糕的部分总是这样一个事实,即C ++的语法对上下文非常敏感。 尽管我喜欢C ++,但对于任何需要编写C ++解析器的人都感到抱歉。


有几件事让C ++编译器比Java / C#编译器慢。 语法要复杂得多,通用编程支持在C ++中更强大,但同时编译成本更高。 包含文件的方式与导入模块的方式不同。

包含头文件

首先,无论何时在C ++中包含文件,文件的内容(通常为.h)都会注入当前编译单元(包含防护避免重复注入相同的头两次),这是传递性的。 也就是说,如果你包含头文件啊,那包括bh,你的编译单元将把所有的代码包含在ah中,并且所有的代码都在bh中

Java(或C#,我会谈论Java,但它们在这方面类似)没有包含文件,它们依赖于编译使用的类的二进制文件。 这意味着,无论何时编译使用b.java中定义的对象B的a.java,它都会检查二进制b.class,它不需要深入检查B的依赖关系,因此它可以更早地切断进程(只有一个级别的检查)。

同时,包括文件只包括语言定义,并且处理它需要时间。 当Java / C#编译器读取二进制文件时,它具有相同的信息,但已经由生成它的编译步骤处理。

所以最后,在C / C ++中包含了更多的文件,同时对这些文件的处理比处理二进制模块更加昂贵。

模板

模板以他们自己的方式很特殊。 它们可以预编译,但通常不会(出于一系列原因)。 这意味着在所有使用std :: vector的编译单元中,使用的整套矢量方法(未使用的模板方法无法编译)将被处理,编译器会生成二进制代码。 在稍后的步骤中,在链接期间,同一方法的冗余定义将会丢失,但在编译期间,它们必须被处理。

Java中对泛型的支持在很多方面受到更多限制。 最后,例如,只有一个Vector类二进制文件,并且只要编译器在Java中看到Vector,它在委托给真实的Vector实现(存储普通对象)之前生成类型检查代码,这不是通用的。 编译器确实提供了类型保证,但不针对每种类型编译Vector。

在C#中,它再次与众不同。 C#对泛型的支持比Java更加复杂,并且最终泛型类与普通类不同,但无论如何它们只能编译一次,因为二进制格式具有所有必需的信息。

链接地址: http://www.djcxy.com/p/14977.html

上一篇: What makes the Java compiler so fast?

下一篇: C++: Where to write the code documentation: in .cpp or in .hpp files?