Skip to content
Go back

C++ 编译性能分析


1. 工具概览

维度工具作用
构建系统统计Ninja -d stats / -d explain任务图、命中/未命中缓存原因
缓存命中率ccache -s / sccache --show-stats缓存效果评估
链接性能lld, gold, bfd + --stats链接耗时
编译分析Clang-ftime-trace各文件/函数,各阶段编译耗时
无用 includeinclude-what-you-use (IWYU) 或 其他静态分析器

2. -ftime-trace

-ftime-trace 由 Clang 提供,会为每个翻译单元(Translation Unit, TU)生成一个统计 JSON。

2.1 单文件示例

clang++ -std=c++20 -O2 -ftime-trace -c test.cpp -o test.o

2.2 CMake 集成

确保使用 Clang:

cmake -DCMAKE_CXX_COMPILER=clang++ -S . -B build

或设置环境变量 CXX=clang++

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  add_compile_options(-ftime-trace -ftime-trace-granularity=200)
endif()

2.3 查看结果

  1. Perfetto UI
  2. Speedscope

在火焰图图中可以看到各种类型的事件所占用的时间比例,可参考下表:

名称说明可能原因
Parse/Class Template Instantiation模板实例化耗时过度泛型、重复实例
Perform Pending Instantiations级联依赖触发头文件结构不佳
CodeGen FunctionIR 生成阶段巨函数 / 大量内联
Backend PassLLVM 优化/寄存器分配等过高优化级别 -O3 / LTO

3. ClangBuildAnalyzer 使用

安装 ClangBuildAnalyzer 后,执行:

ClangBuildAnalyzer --all ./build ./report.bin
ClangBuildAnalyzer --analyze ./report.bin

这里贴一个来自原作者的图:

ClangBuildAnalyzer
ClangBuildAnalyzer

结果中能看到,clang 前后端处理耗时主要在哪些地方,最耗时的模板,最昂贵的头文件(在哪里被引用,被引用了多少次)等等信息,后续可以针对性拆分头文件,加快编译速度。

笔者在自己的工程里面,通过以上方式,将原版编译耗时 6 分 40 秒,优化到了 4 分 20 秒,体验提升很大。


4. 参考

  1. Perfetto Trace Viewer: https://perfetto.dev/
  2. Speedscope Flamegraph Viewer: https://www.speedscope.app/
  3. ClangBuildAnalyzer GitHub: https://github.com/aras-p/ClangBuildAnalyzer
  4. PImpl Idiom – C++ Core Guidelines discussion: https://isocpp.org/wiki/faq/pimpl
  5. Include What You Use: https://include-what-you-use.org/
  6. Extern Template (cppreference): https://en.cppreference.com/w/cpp/language/class_template#Extern_template
  7. CMake target_precompile_headers Documentation: https://cmake.org/cmake/help/latest/command/target_precompile_headers.html
  8. ccache Official Site: https://ccache.dev/
  9. sccache GitHub: https://github.com/mozilla/sccache
  10. LLD Performance (LLVM blog / benchmarks): https://lld.llvm.org/
  11. ThinLTO Design – LLVM: https://llvm.org/docs/ThinLTO.html


Share this post on: