Headers 编译速度更快?

Headers compiling faster?

我想更深入地了解为什么使用 headers,经过一些研究,我找到了一些令人信服的答案,但在大多数回复中,人们说它使编译速度更快,但所有这些答案都含糊不清,而且不要确切地说 headers 如何使编译更容易。 有人可以更深入地探讨这个主题吗? 谢谢

忘记编译速度吧。问题是软件的可维护性。

Headers 旨在包含不同来源在编译时所需的内容,通常是构成 API.

的#define 常量和函数声明

如果您是从头开始编译,将项目分成 headers 不会提高编译速度。

但是,它们可以更快地修改代码。项目的编译通常是这样的。首先,将每个文件编译成具有相对地址的机器代码(因此代码的起始地址未知)。然后你 link 所有其他文件来创建你的项目。

假设您有一个包含 10.000 个文件的项目。如果您仅更改 1 个文件,则在构建项目时将仅编译该文件,然后所有其他文件都将被 linked。如果您没有将项目划分为 10,000 个文件,那么在构建一个简单的更改时,您将不得不编译所有其他 10,000 个文件。因此,一旦您编译了项目,使用这种方法调试就会变得非常快。

另外,编译文件是一个单线程程序。因此,您可以通过将多个文件编译在一起来并行化编译速度。 -j make 命令的标志执行此操作。

一些编译器(实际上只是 MSVC)可以充分利用预编译的 headers。这实际上意味着如果您在每个编译单元的开头都有相同的包含文件,那么您可以告诉编译器只处理一次,并且对于每个其他编译单元只在包含之后立即开始处理。

如果您看到带有 stdafx.h header 的项目引入了整个项目中常用的许多其他 header,那么就是这样。

gcc 或 clang 等其他编译器处理源代码的速度要快得多,因此缓存这种不完整的表示尚无任何好处。


除了预编译的 header 之外,它们还充当编译单元之间的通用接口。当谈论带有模板的 C++ 或模板生成过多代码的 C 时,在编译阶段将结果符号的可见性限制为仅对特定编译单元的可见性有时会有所不同。为了在接下来的 link 阶段限制可见性,可以使用 static 关键字。

实际上这不会影响大多数项目。事实上,对于较小的项目,一种常见的技术实际上是在编译之前连接所有编译单元,以便在编译时消除分离,而无需专门的 link 步骤。考虑到合并编译单元的静态符号没有冲突,与 header.

中严格使用最小接口相比,这实际上往往会节省更多的编译时间。

根据实际经验估计,一旦单个编译单元中的可见符号超过 50-100k,您就需要开始出于编译器性能原因降低可见性。