java 编译时长_为什么C ++编译需要这么长时间?

几个原因

头文件

每个编译单元都需要数百甚至数千个头文件(1)加载和(2)编译。通常必须为每个编译单元重新编译它们中的每一个,因为预处理器确保编译头的结果可能在每个编译单元之间变化。(可以在一个编译单元中定义宏,该编译单元改变标题的内容)。

这可能是主要原因,因为它需要为每个编译单元编译大量代码,此外,每个头文件必须多次编译(每个编译单元包含它一次)。

链接

编译完成后,所有目标文件必须链接在一起。这基本上是一个单一的过程,不能很好地并行化,并且必须处理整个项目。

解析

解析时语法极其复杂,在很大程度上取决于上下文,并且很难消除歧义。这需要很多时间。

模板

在C#中,List无论你在程序中有多少个List实例,它都是唯一被编译的类型。在C ++中,vector是一个完全独立的类型vector,每个都必须单独编译。

除此之外,模板构成了编译器必须解释的完整图灵完整的“子语言”,这可能变得非常复杂。即使是相对简单的模板元编程代码也可以定义递归模板,这些模板可以创建数十个模板实例。模板也可能导致极其复杂的类型,名称冗长,为链接器添加了大量额外的工作。(它必须比较许多符号名称,如果这些名称可以增长到数千个字符,那可能会变得相当昂贵)。

当然,它们会加剧头文件的问题,因为模板通常必须在头文件中定义,这意味着必须为每个编译单元解析和编译更多的代码。在普通的C代码中,标头通常只包含前向声明,但实际代码很少。在C ++中,几乎所有代码都驻留在头文件中并不罕见。

优化

C ++允许一些非常戏剧性的优化。C#或Java不允许完全删除类(它们必须用于反射目的),但即使是简单的C ++模板元程序也可以轻松生成数十个或数百个类,所有这些类都在优化中被内联并消除相。

此外,编译器必须完全优化C ++程序。AC#程序可以依赖JIT编译器在加载时执行额外的优化,C ++没有得到任何这样的“第二次机会”。编译器生成的内容是最优化的。

C ++被编译为机器代码,这可能比字节码Java或.NET使用更复杂(特别是在x86的情况下)。(这完全是出于完整性而被提及,因为它在评论等中提到过。在实践中,这一步骤不太可能占用总编译时间的一小部分)。

结论

大多数这些因素都由C代码共享,实际上编译效率相当高。解析步骤在C ++中要复杂得多,并且可以占用更多的时间,但主要的攻击者可能是模板。它们很有用,并且使C ++成为一种更强大的语言,但它们也会在编译速度方面付出代价。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值