21

我想减少大型 C++ 项目的编译时间。我尝试使用预编译的头文件、接口等。但在继续之前,我想知道是否有任何工具可以帮助检测为什么编译时间这么长。有人建议使用 pc-lint,我会试一试。 我应该如何检测大型 C++ 项目中不必要的#include 文件? 但是,如果有其他工具可以分析编译时间并谈论任何提高编译速度的提示,请告诉我。提前致谢。

环境:Microsoft Visual Studio C++ 2008 或 2010。

4

4 回答 4

5

我喜欢的一种方法是查看您的一些源的预处理器输出——只需从编译器的角度阅读其中的一些,而不是#inclusion 的某种抽象表示。您可能会发现一些您不需要的大块包含/库,并且不一定知道依赖项/包含的存在(或需要)。从那里,决定可以删除哪些依赖项。即使您的依赖关系都是正确的,大输出也可以建议您如何较大的模块划分为较小的部分。

于 2012-05-14T06:16:42.990 回答
4

C++还不是模块化的(还),编译瓶颈通常是由于包含问题;即在不需要时使用包含太多文件。目前也可能需要这些包含,但通过一些简单的重新设计可能会变得多余。

  • 要检测多余的包含,您可以检查include-what-you-use,您将遇到的唯一问题是它在 Clang 之上工作,因此您需要在那里进行一些设置。
  • 否则,您需要查看您的代码,特别是headers

由于该工具是自给自足的并且有文档记录,因此让我对审查过程进行一些扩展。

  1. 任何包含两个以上的标题#include都是高度可疑的。
  2. 相反,如果您的源文件塞满了各种类型和功能,而它只有几个包含,则可能意味着其中一个标题带来了太多。

如果您不知道什么是必需的,什么不是,以及如何删除多余的标题,我建议您阅读Pimpls - Beauty Marks You Can Depend On;如果您不知道 Pimpl 是什么,请阅读编译防火墙。不过,我建议谨慎行事,Pimpl 具有运行时和维护成本,因此仅在确实需要时才使用它。就个人而言,我绝对会在您提供给第三方的库的公共标头中推荐它(ABI 兼容性),否则尽量避免它。

如果手动检查不是您的强项,您可以为每个标头生成预处理器输出(不要太担心源文件),然后检查更大的输出。

于 2012-05-14T06:46:53.883 回答
3

我不知道有任何工具可以改善编译时间,但我可以建议很少的手动补救措施(将此视为评论):

  1. 对每个头文件都有#include保护,这样多个包含就不会产生任何问题
  2. 减少成员函数体,内联函数体直接放入头文件;只要有他们的声明
  3. 检查是否没有不必要的template函数和类;请记住,模板inline是默认的。太多的模板/元编程会导致巨大的编译时间。
  4. 如果#defines 的数量不必要地高,那么它们会增加预处理阶段,最终增加编译时间
于 2012-05-14T05:24:03.157 回答
2

You could look into unity builds.
Basically it's including all .cpp files into one .cpp file and only compiling that one file. I've tested it on a big project and it was really effective.
It works because of it uses much less I/O when it includes all your headers/cpp's once and not for every cpp.

Now we don't use unity builds anymore because we all got a SSD hardware upgrade, and they are just awesome.

Here's a related SO question about Unity builds: #include all .cpp files into a single compilation unit?

于 2012-05-14T09:45:38.037 回答