我应该如何检测大型C ++项目中编译时间的瓶颈?

时间:2023-01-13 10:45:18

I want to reduce compile time of a large C++ project. I tried to use precompiled headers, interface and etc. But before I move on, I want to know whether any tool which helps detect why compile time is so long. Somebody suggests pc-lint and I will give a shot. How should I detect unnecessary #include files in a large C++ project? But if there are other tools which analysis compile time and talk about any hints to increase compile speed, let me know. Thanks in advance.

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

Environment : Microsoft Visual Studio C++ 2008 or 2010.

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

4 个解决方案

#1


5  

one approach i like is to review the preprocessor output of a few of your sources -- just read some of it from the compiler's perspective rather than the somewhat abstracted representation that is #inclusion. chances are you will find some large chunks of includes/libraries you don't need and weren't necessarily aware of the existence (or need) of the dependency/include. from there, decide which dependencies can be removed. even if your dependencies were all correct, large outputs can also suggest how you might approach dividing larger modules into smaller pieces.

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

#2


4  

C++ not being modular (yet), compilation bottlenecks are often due to include issues; that is using including too many files when they are not needed. It is also possible that those includes are needed at the moment, but could become superfluous with some simple reengineering.

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

  • to detect superfluous includes, you can check include-what-you-use, the only issue you'll have is that it works on top of Clang, so you'll need some setup there.
  • 为了检测多余的包含,你可以检查包括你使用的,你唯一的问题是它在Clang之上工作,所以你需要在那里进行一些设置。

  • otherwise, you need to review your code, and specifically the headers.
  • 否则,您需要检查您的代码,特别是标题。

Since the tool is self-sufficient and documented, let me expand a bit on the review process.

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

  1. Any header that has more than a couple #include is highly suspicious.
  2. 任何包含多个#include的标头都非常可疑。

  3. On the contrary, if you have a source file chock-full of various types and functions and it only has a couple includes, it probably means that one of the headers brings too much.
  4. 相反,如果你有一个充满各种类型和功能的源文件,它只有一对包含,它可能意味着其中一个标题带来了太多。

If you have trouble knowing what is required, what is not, and how to remove superfluous headers, I recommend a reading of Pimpls - Beauty Marks You Can Depend On; if you do not know what a Pimpl is, read Compilation Firewalls. I would advise cautiousness though, Pimpl has a runtime and maintenance cost, so only use it when it really is necessary. Personally I would absolutely recommend it in the public headers of a library you deliver to 3rd party (ABI compatibility), and otherwise try to avoid it.

如果你不知道什么是必需的,什么不是,以及如何删除多余的标题,我建议阅读Pimpls - 你可以依赖的美丽标记;如果您不知道Pimpl是什么,请阅读编译防火墙。我建议谨慎,Pimpl有运行时和维护成本,所以只有在必要时才使用它。就个人而言,我绝对会在你提供给第三方(ABI兼容性)的图书馆的公共标题中推荐它,否则会尽量避免它。

If manual inspection is not your forte, you can generate the preprocessor output for each header (do not worry about source files too much), and check the bigger outputs.

如果手动检查不是你的强项,你可以为每个标题生成预处理器输出(不要过多担心源文件),并检查更大的输出。

#3


3  

I am not aware of any tool for betterment of the compile time, but few manual remedies, I can suggest (consider this as comment):

我不知道有任何改进编译时间的工具,但很少有人工补救措施,我可以建议(认为这是评论):

  1. Have #include guards with every header file, so that multiple inclusions won't make any issues
  2. 每个头文件都包含#include guards,因此多个包含不会产生任何问题

  3. Reduce member function body, inline function body putting directly into the header files; just have their declarations
  4. 减少成员函数体,内联函数体直接放入头文件;只是有他们的声明

  5. Check if there are no unnecessary template function and classes; remember that tempaltes become inline by default. Too much of templates/metaprogramming cause huge compilation time.
  6. 检查是否没有不必要的模板函数和类;请记住默认情况下tempaltes变为内联。太多的模板/元编程会导致大量的编译时间。

  7. If number of #defines are unnecessarily high then they would increase preprocessing stage, which ultimately increases the compilation time
  8. 如果#defines的数量不必要地高,那么它们将增加预处理阶段,这最终会增加编译时间

#4


1  

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.

你可以看看统一构建。基本上它将所有.cpp文件包含在一个.cpp文件中,并且仅编译该文件。我在一个大项目上测试了它,它真的很有效。它的工作原理是它包含所有标题/ cpp一次而不是每个cpp时使用的I / O少得多。

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

现在我们不再使用unity build了,因为我们都有SSD硬件升级,而且它们真棒。

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

这是一个关于Unity构建的相关SO问题:#include所有.cpp文件到一个编译单元?

#1


5  

one approach i like is to review the preprocessor output of a few of your sources -- just read some of it from the compiler's perspective rather than the somewhat abstracted representation that is #inclusion. chances are you will find some large chunks of includes/libraries you don't need and weren't necessarily aware of the existence (or need) of the dependency/include. from there, decide which dependencies can be removed. even if your dependencies were all correct, large outputs can also suggest how you might approach dividing larger modules into smaller pieces.

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

#2


4  

C++ not being modular (yet), compilation bottlenecks are often due to include issues; that is using including too many files when they are not needed. It is also possible that those includes are needed at the moment, but could become superfluous with some simple reengineering.

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

  • to detect superfluous includes, you can check include-what-you-use, the only issue you'll have is that it works on top of Clang, so you'll need some setup there.
  • 为了检测多余的包含,你可以检查包括你使用的,你唯一的问题是它在Clang之上工作,所以你需要在那里进行一些设置。

  • otherwise, you need to review your code, and specifically the headers.
  • 否则,您需要检查您的代码,特别是标题。

Since the tool is self-sufficient and documented, let me expand a bit on the review process.

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

  1. Any header that has more than a couple #include is highly suspicious.
  2. 任何包含多个#include的标头都非常可疑。

  3. On the contrary, if you have a source file chock-full of various types and functions and it only has a couple includes, it probably means that one of the headers brings too much.
  4. 相反,如果你有一个充满各种类型和功能的源文件,它只有一对包含,它可能意味着其中一个标题带来了太多。

If you have trouble knowing what is required, what is not, and how to remove superfluous headers, I recommend a reading of Pimpls - Beauty Marks You Can Depend On; if you do not know what a Pimpl is, read Compilation Firewalls. I would advise cautiousness though, Pimpl has a runtime and maintenance cost, so only use it when it really is necessary. Personally I would absolutely recommend it in the public headers of a library you deliver to 3rd party (ABI compatibility), and otherwise try to avoid it.

如果你不知道什么是必需的,什么不是,以及如何删除多余的标题,我建议阅读Pimpls - 你可以依赖的美丽标记;如果您不知道Pimpl是什么,请阅读编译防火墙。我建议谨慎,Pimpl有运行时和维护成本,所以只有在必要时才使用它。就个人而言,我绝对会在你提供给第三方(ABI兼容性)的图书馆的公共标题中推荐它,否则会尽量避免它。

If manual inspection is not your forte, you can generate the preprocessor output for each header (do not worry about source files too much), and check the bigger outputs.

如果手动检查不是你的强项,你可以为每个标题生成预处理器输出(不要过多担心源文件),并检查更大的输出。

#3


3  

I am not aware of any tool for betterment of the compile time, but few manual remedies, I can suggest (consider this as comment):

我不知道有任何改进编译时间的工具,但很少有人工补救措施,我可以建议(认为这是评论):

  1. Have #include guards with every header file, so that multiple inclusions won't make any issues
  2. 每个头文件都包含#include guards,因此多个包含不会产生任何问题

  3. Reduce member function body, inline function body putting directly into the header files; just have their declarations
  4. 减少成员函数体,内联函数体直接放入头文件;只是有他们的声明

  5. Check if there are no unnecessary template function and classes; remember that tempaltes become inline by default. Too much of templates/metaprogramming cause huge compilation time.
  6. 检查是否没有不必要的模板函数和类;请记住默认情况下tempaltes变为内联。太多的模板/元编程会导致大量的编译时间。

  7. If number of #defines are unnecessarily high then they would increase preprocessing stage, which ultimately increases the compilation time
  8. 如果#defines的数量不必要地高,那么它们将增加预处理阶段,这最终会增加编译时间

#4


1  

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.

你可以看看统一构建。基本上它将所有.cpp文件包含在一个.cpp文件中,并且仅编译该文件。我在一个大项目上测试了它,它真的很有效。它的工作原理是它包含所有标题/ cpp一次而不是每个cpp时使用的I / O少得多。

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

现在我们不再使用unity build了,因为我们都有SSD硬件升级,而且它们真棒。

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

这是一个关于Unity构建的相关SO问题:#include所有.cpp文件到一个编译单元?