为何使用g++预编译头后编译速度未得到提升?
g++预编译头测试问题解析
测试场景
测试代码
main.cpp
#include "header.hpp" int main() { std::cout << "Hello world !" << std::endl; }
header.hpp
#include <iostream> #include <algorithm> #include <functional> #include <memory> #include <thread> #include <utility> #include <string> #include <stack> #include <deque> #include <array> #include <vector> #include <set> #include <map> #include <unordered_set> #include <unordered_map>
编译过程
- 正常编译项目
$ time g++ main.cpp real 0m0.738s user 0m0.646s sys 0m0.070s
- 生成预编译头后重新编译
$ g++ header.hpp # 生成header.hpp.gch $ time g++ main.cpp real 0m0.721s user 0m0.626s sys 0m0.072s
编译速度几乎无变化,疑惑预编译头的作用及是否操作有误。
问题分析
操作有误:预编译头参数不匹配
g++使用预编译头的核心要求是:生成预编译头的编译参数,必须和后续编译源文件的参数完全一致。你直接用g++ header.hpp生成预编译头,默认参数可能和编译main.cpp时的隐含参数存在差异(比如标准版本、优化级别、宏定义等),这会导致编译器直接忽略预编译头,重新解析header.hpp。
正确的操作方式是,生成预编译头时使用和编译main.cpp完全相同的参数,比如:
# 生成预编译头,指定C++标准版本(和后续编译保持一致) $ g++ -std=c++17 header.hpp # 编译main.cpp,使用相同参数 $ time g++ -std=c++17 main.cpp
测试用例太小,效果被掩盖
你的测试项目只有一个几行代码的main.cpp,编译耗时主要集中在编译器启动和链接阶段,预编译头节省的头文件解析时间占比极低,所以看不出明显差异。如果是包含十几个甚至几十个依赖该头文件的源文件的大型项目,预编译头带来的速度提升会非常显著。
预编译头的实际作用
- 减少重复解析开销:对于包含大量标准库、第三方库头文件的项目,每次编译都要重复解析这些头文件会耗费大量时间,预编译头将解析结果缓存,所有源文件直接复用,大幅缩短编译时间
- 降低内存占用:重复解析头文件会导致编译器内存占用飙升,预编译头能减少内存消耗,提升编译稳定性
- 统一编译环境:预编译头可以确保所有源文件使用相同的头文件解析结果,避免因头文件包含顺序或宏定义差异导致的编译问题
内容的提问来源于stack exchange,提问作者Autechre
相关产品推荐
相关产品推荐

