在大型C++项目中,我应该如何检测编译时间的瓶颈
How should I detect bottleneck of compile time in a large C++ project?
我想减少大型C++项目的编译时间。我尝试使用预编译的标头,接口等。但在我继续之前,我想知道是否有任何工具可以帮助检测为什么编译时间这么长。有人建议 pc-lint 我会试一试。如何检测大型C++项目中不必要的 #include 文件?但是,如果还有其他工具可以分析编译时间并谈论任何提高编译速度的提示,请告诉我。提前谢谢。
环境:Microsoft Visual Studio C++ 2008或2010
的一种方法是查看一些源代码的预处理器输出 - 只需从编译器的角度阅读其中的一些内容,而不是#inclu
sion的抽象表示。 您可能会发现一些您不需要的大块包含/库,并且不一定知道依赖项/包含的存在(或需要(。 从那里, 确定可以删除哪些依赖项。即使依赖项都是正确的,较大的输出也可以建议如何将较大的模块划分为较小的部分。
C++还不是模块化的,编译瓶颈通常是由于包含问题造成的;即在不需要文件时使用包含太多文件。目前也可能需要这些包含,但通过一些简单的重新设计可能会变得多余。
- 要检测多余的包含,您可以检查包含您使用的内容,您唯一的问题是它可以在 Clang 之上工作,因此您需要在那里进行一些设置。
- 否则,您需要查看代码,特别是标头。
由于该工具是自给自足的并且有文档记录,因此让我对审查过程进行一些扩展。
- 任何具有多个
#include
的标头都是高度可疑的。 - 相反,如果你有一个充满各种类型和功能的源文件,而它只有几个包含,这可能意味着其中一个标题带来了太多。
如果你不知道什么是必需的,什么不是,以及如何删除多余的标题,我建议阅读Pimpls - 你可以依赖的美丽标记; 如果您不知道什么是 Pimpl,请阅读编译防火墙。不过,我建议谨慎行事,Pimpl 具有运行和维护成本,因此仅在真正必要时使用它。就个人而言,我绝对建议您在提供给第三方(ABI 兼容性(的库的公共标头中使用它,否则尽量避免它。
如果手动检查不是您的强项,您可以为每个标头生成预处理器输出(不要太担心源文件(,并检查较大的输出。
有任何工具可以改善编译时间,但我可以建议很少手动补救措施(将其视为评论(:
- 对每个头文件都有
#include
保护,以便多个内含物不会产生任何问题 - 减少成员函数体,内联函数体直接放到头文件中;只要有他们的声明
- 检查函数和类是否没有不必要的
template
;请记住,默认情况下,临时态会变为inline
。太多的模板/元编程会导致巨大的编译时间。 - 如果
#define
的数量不必要地高,那么它们会增加预处理阶段,最终增加编译时间
你可以看看 Unity 构建。
基本上,它将所有.cpp
文件包含在一个.cpp文件中,并且只编译该文件。我在一个大项目中测试过它,它真的很有效。
它之所以有效,是因为当它一次包含所有标头/cpp 而不是每个 cpp 时,它使用的 I/O 要少得多。
现在我们不再使用 Unity 构建,因为我们都进行了 SSD 硬件升级,它们非常棒。
这里有一个关于 Unity 构建的相关 SO 问题:将所有.cpp文件 #include 到一个编译单元中?
- 编译的C可执行文件被Windows defender检测为病毒
- CodeLite 不会检测(安装)MinGW - 即使使用手动配置也不会编译
- 检测编译时文本和常量
- 如何在编译时检测C 17中是否没有虚拟基础
- 有没有办法在编译时检测是否可以使用一组给定的参数类型成功调用通用 lambda?
- 编译时未检测到主要功能
- 参数类型的编译时类型检测
- 使用SFINAE检测编译时间是否存在过载的独立式功能
- 如何在编译时检测 C++ 代码中的 SQL 错误
- 如何在编译时检测ABI
- 我可以检测编译时使用的标记调度重载吗?
- 如何检测编译时是否shared_ptr类型
- 检测或避免在编译时间上暂时提及暂时的提及
- 在编译时检测std :: size_t类型以调用正确的功能
- 编译共享对象时出错:未检测到C++类定义
- 在编译时检测是否存在默认构造函数
- 编译弃用电话的时间检测
- 是否可以在编译时间作为宏上检测GCC编译标志
- 检测编译时是否存在长长
- 在大型C++项目中,我应该如何检测编译时间的瓶颈