Accelerate the Compiling Speed by Using Pre-compiled Header

前言

这是2009年我在项目组做的一个改进。项目大约有80万行的代码(现在已过百万),编译非常慢。当时大家苦不堪言,工作效率很低。预编译头文件可以大幅提高编译效率。在一些尝试之后,我写了一个Python脚本,把工程中的常用头文件提取出来做成预编译头,也成为组里为数不多的,把全部代码Check out的工程师。你可以在这找到Python的脚本。

Introduction

This article is trying to explain why and how to use pre-compiled header file to accelerate our projects compiling(not including linking) speed.

Motivation

In our daily work, we modify code for fixing bugs or implementing new features, and then build new binary file and test it. The building process usually costs between 3~20 minutes. And sometimes we have to sync other colleagues’ code, the building process is much longer. So accelerating building speed is very important to improve our efficiency. Building process contains two steps. One is to compile source files and generate object files, the other is to link all object files together and generate binary file. This artical is focus on accelerating the first step.

How to use pre-compiled header

Right now many compilers, including VC++ compiler and GCC, supply a technology called pre-compiled header, which can greatly improve the compiling efficiency. Assumed there is a structure of source files.

A.cpp incudes the wx/wx.h and also does B.cpp and C.cpp. When compiling A.cpp, B.cpp and C.cpp, the compiler will parse the wx/wx.h three times. wx/wx.h is a quitely-often-used header file in our project. And there are hundreds of source files in our projects. So the wx/wx.h will be parsed hundreds of times. And there are many often-used header files like header files in std(Standard Template Library) and wxWidgets.

Pre-compiled header technology uses a common header file to generated pre-compiled header file(.pch using by VC++, .gch using by GCC). The common header file contains as many as often-used header files and we seldom change it. The former structure should be changed like the following schematic.

Now the header file called “stdwx.h” contains other often-used header files. Since the header file can not be compiled, stdwx.cpp is used to generate the pre-compiled header file. And we need to change the project build configuration like below.

For VC++

For whole project,

NOTE: Actually, we can change the configuration for every single source(.cpp) file using the same method. But project-level setting is much more convenient, it can change the other source file configuration, except for those already have their own setting of precompiled header.

For stdwx.cpp,

NOTE:  stdwx.cpp is special, since the header(.h) file can not be compiled by compiler. We need a cpp file to let the compiler to compile. The content of stdwx.cpp is very simple, just include stdwx.h. So compiler will use stdwx.cpp to generate the precompiled header.

For GCC

GCC supports a compile option called -x c++-header (for cpp) and c-header(for c), which used to generate the precompiled header file. Please see the following statements in makefiles.

After that, when compiler compiles the A.cpp, B.cpp and C.cpp, the stdwx.h will be parsed only once by compiling stdwx.cpp. That how the time is saved!

NOTE: The source files using pre-compiled header should include “stdwx.h” at the first line of the source, or there will be compiling errors!

Test Result

The test result is very exciting! Project has 80,000 LoC.

With Pre-compiled Header Without Pre-compiled Header
Re-build Time(NOT including linking time) 30~35min 130min+

The re-build time with pre-compiled head is only about 23% of that of without pre-compiled header project. In other words, the compiling efficiency is improved over 70%.