[c++] 为什么C ++编译需要这么长时间?



Answers

任何编译器的放缓都不一定相同。

我没有使用Delphi或Kylix,但回到MS-DOS时代,Turbo Pascal程序几乎可以立即编译,而等效的Turbo C ++程序只会抓取。

两个主要区别是一个非常强大的模块系统和允许单次编译的语法。

对于C ++编译器开发人员来说,编译速度当然不是优先考虑的事情,但C / C ++语法中也存在一些固有的复杂性,这使得它更难处理。 (我不是C方面的专家,但Walter Bright是,并且在构建各种商业C / C ++编译器之后,他创建了D语言。 他的一个变化是强制使用上下文无关语法来使语言更易于解析。)

另外,您会注意到,通常会设置Makefiles,以便每个文件都在C中分别编译,因此如果10个源文件全部使用相同的包含文件,则包含文件将被处理10次。

Question

与C#和Java相比,编译C ++文件需要很长时间。 编译C ++文件比运行普通大小的Python脚本要花费更长的时间。 我目前正在使用VC ++,但对于任何编译器都是一样的。 为什么是这样?

我能想到的两个原因是加载头文件和运行预处理器,但这似乎并不能解释为什么它需要这么长时间。




你得到的折衷是程序运行速度更快。 在开发过程中,这可能会让你感到很冷淡,但一旦开发完成,这可能会很重要,并且该程序正在由用户运行。




编译语言总是需要比解释语言更大的初始开销。 另外,也许你没有很好地构建你的C ++代码。 例如:

#include "BigClass.h"

class SmallClass
{
   BigClass m_bigClass;
}

编译比以下更慢:

class BigClass;

class SmallClass
{
   BigClass* m_bigClass;
}



正如已经评论的那样,编译器花费大量的时间来实例化和实例化模板。 在这样的情况下,有些项目专注于该特定项目,并声称在某些真正有利的情况下可观察到30倍的加速。 请参阅http://www.zapcc.com




最大的问题是:

1)无限标题重新分析。 已经提到。 缓解(像#pragma一次)通常只对每个编译单元有效,而不是每个构建。

2)工具链经常被分成多个二进制文件(在极端情况下为make,预处理器,编译器,汇编器,归档器,impdef,链接器和dlltool),每次调用都必须重新初始化并重新加载所有状态编译器,汇编程序)或每一对文件(存档器,链接器和dlltool)。

另请参阅comp.compilers上的这个讨论: http://compilers.iecc.com/comparch/article/03-11-078 ://compilers.iecc.com/comparch/article/03-11-078特别是这一个:

http://compilers.iecc.com/comparch/article/02-07-128

请注意,comp.compilers的主持人John似乎同意这一点,并且这意味着如果一个工具链完全集成并实现预编译头文件,那么也应该可以为C实现类似的速度。 许多商业C编译器在一定程度上做到了这一点。

请注意,将所有东西都分解成单独二进制文件的Unix模型是Windows的一种最差情况模型(创建过程缓慢)。 比较Windows和* nix之间的GCC编译时间是非常明显的,特别是如果make / configure系统也调用一些程序来获取信息。




大多数答案都有点不清楚,提到C#总是会运行得慢一些,因为在编译时只执行一次C ++的执行操作的代价,这种性能成本也受到运行时依赖关系的影响(需要加载更多的东西运行),更不用说C#程序总是会有更高的内存占用量,所有这些都导致性能与硬件的可用性更密切相关。 其他解释或依赖虚拟机的语言也是如此。




C ++被编译成机器码。 所以你有预处理器,编译器,优化器,最后是汇编器,所有这些都必须运行。

Java和C#被编译为字节码/ IL,并且Java虚拟机/ .NET Framework在执行之前执行(或JIT编译为机器码)。

Python是一种解释型语言,也被编译为字节码。

我确信还有其他原因,但一般来说,不需要编译为本地机器语言可以节省时间。






Related