65.9K
CodeProject 正在变化。 阅读更多。
Home

如何通过预编译头文件(PCH 文件)优化编译时间

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (6投票s)

2017年5月25日

CPOL

3分钟阅读

viewsIcon

18280

您是否好奇预编译头文件(或 .pch 文件)究竟是什么,以及为什么要使用它们?本文将介绍这些内容,并提供一个如何使用它们的示例。

点击此处免费下载 IncrediBuild,加速您的 C++ 开发.

什么是头文件?

如果您问这个问题,那么您很可能刚接触 C 和 C++(老实说,快速复习一下总没坏处。)

头文件(.h 扩展名)在 C 和 C++ 中用于定义函数、模板和宏的结构,这些结构可以包含在一个或多个源文件中。这个概念是在 20 世纪 70 年代引入的,当时仅加载头文件是节省宝贵内存和其他系统资源的一种方式。

当然,自 20 世纪 70 年代以来,我们已经走了很长一段路,而且在大多数系统上,内存可能不再是如此稀缺的商品。但尽可能精简高效总是好的,而头文件在实现这一目标方面发挥着重要作用。

世界上最著名的头文件是 stdio.h,它位于为 C 编写的每个“hello world”示例应用程序的顶部,其中包括将文本写入控制台的实际 printf 函数的结构。

$ cat hello-world.c
#include <stdio.h>
int main() {
   printf("Hello World\n");
   return 0;
}

什么是预编译头文件?

预编译头文件的名称表明了它的含义。在 C/C++ 应用程序的编译过程中,编译头文件的步骤已经完成。拥有已经编译好的头文件可以显著减少编译时间。

预编译头文件如何工作?

预编译头文件的工作原理是保留上次运行时编译的头文件。 第一次编译项目时,如果您已配置为支持预编译头文件,则编译器和支持工具(如 nmake 或 ant)将编译头文件并生成 PCH 文件。

第二次和后续时间运行编译器时,它会将头文件与上次编译的内容进行比较,如果没有任何更改,它将使用预编译头文件。这就是为什么提前正确地构建头文件,并拥有一个相对稳定的代码库,才能真正发挥这种性能增强方法的优势。

在流行的编译器上启用预编译头文件

如果您正在使用 Visual Studio 并且有兴趣启用预编译头文件,请阅读 MSDN 上关于该主题的文档

GCC 也有关于启用预编译头文件的文档。

如果您更喜欢 Intel 的编译器,它也完全支持预编译头文件

使用预编译头文件可以带来的时间差异示例

让我们创建一个非常简单的程序。

$ cat header.h 
#include <CoreFoundation/CoreFoundation.h>
#include <objc/objc.h>
#include <objc/objc-runtime.h>
#include <iostream>

$ cat simple.cpp 
#include "header.h"
int main() {
  return 0;
}

并记录编译时间

$ time g++ -std=c++11 simple.cpp -o simple

real	0m1.152s
user	0m0.424s
sys	0m0.585s

现在让我们预编译头文件,然后重新编译以记录时间

$ g++ -std=c++11 header.h
$ time g++ -std=c++11 simple.cpp -o simple

real	0m0.601s
user	0m0.411s
sys	0m0.149s

注意到区别了吗?它节省了半秒钟。现在想象一下大规模情况下的差异。

结论和额外的编译时间优化

对于任何代码库来说,预编译头文件都是减少应用程序编译时间的绝佳第一步——最大的一个需要注意的是,应用程序代码库需要进行结构化,才能真正利用它。启用预编译头文件并非万能药,但它通常会有一些帮助——并且通过一些努力或预先规划,可以提供很大的帮助。(如果您想了解更多背景信息,可以查看支持反对预编译头文件的论点。)

如果您想进一步缩短编译时间,或者有一个特别复杂的项目,在开始时没有考虑预编译头文件,比如 Xbox 游戏,那么您可以采取其他步骤。其中最重要的一步是大规模并行化您的编译过程。从桌面上的四个核心到服务器场上的 400 甚至更多核心,总不会有坏处,对吧?诀窍在于拥有可用的服务器容量,并拥有适当的流程和工具来管理构建,以便所有内容仍然以正确的顺序完成,并在最后正确组装。

这就是 IncrediBuild 等公司发挥作用的地方。他们提供的服务从可以集成到 IDE 中的插件开始,支持预编译头文件,协助测试自动化,并提供具有您所需容量的云服务,以使您的编译更具时间效率。他们已经看到了高达 90% 的编译时间缩短。

© . All rights reserved.