Every C++ header in a project as a precompiled header

点点圈 提交于 2021-02-10 13:38:19

问题


The usual approach is to have one precompiled header in a project that contains the most common includes.

The problem is, that it is either too small or two big. When it is too small, it doesn't cover all the used headers so these have to be processed over and over in every module. When it is too large, it slows down the compilation too much for two reasons:

  1. The project needs to be recompiled too often when you change something in header contained in the precompiled header.
  2. The precompiled header is too large, so including it in every file actually slows down compilation.

What if I made all of the header files in a project precompiled. This would add some additional compiler work to precompile them, but then it would work very nicely, as no header would have to be processed twice (even preparing the precompiled header would use precompiled headers recursively), no extra stuff would have to be put into modules and only modules that are actually needed to be recompiled would be recompiled. In other words, for extra work O(N) complexity I would (theoretically) optimise O(n^2) comlexity of C++ includes. The precosseor to O(N), the processing of precompiled data would still be O(N^2), but at least minimised.

Did anyone tried this? Can it boost compile times in real life scenarios?


回答1:


With GCC, the reliable way to use precompiled headers is to have one single (big) header (which #include-s many standard headers ...), and perhaps include some small header after the precompiled one.

See this answer for a more detailed explanation (for GCC specifically).




回答2:


My own experience with GCC and Clang with precompiled headers is that you only can give a single pre-compiled header per compilation. See also the GCC documentation, I quote:

A precompiled header file can be used only when these conditions apply:

  • Only one precompiled header can be used in a particular compilation.
  • ...

In practice, it's possible to compile every header to a precompiled header. (Recommended if you want to verify if everything is included, not recommended if you want to speed up compilation)

Based on your code, you can decide to use a different precompiled header based on the code that needs to be compiled. However, in general, it's a balancing act between compile time of the headers, compile-time of the CPP files and maintenance.

Adding a simple precompiled header that already contains several standard headers like string, vector, map, utility ... can already speed up your compilation with a remarkable percentage. (A long time ago, I've noticed a 15-20% on a small project)

The main gain you get from precompiled headers is that it:

  • only have to read 1 file instead of more, which improves on disk access
  • reads a binary format that's optimized for reading instead of plain text
  • it doesn't need to do all of the error checking as this was already done on creation

Even if you add a few headers that you don't use everywhere, it can still be much faster.

Lately, I also found the Clang build analyzer, it ain't ideal for big projects (see issue on github), though, it can give you some insights on where the time is being spent and what it can improve. (Or what you can improve in the codebase)

In all fairness, I don't use precompiled headers at this point in time. However, I do want to see it enabled on the project I'm working on.

Some other interesting reads:

  • https://medium.com/@unicorn_dev/speeding-up-the-build-of-c-and-c-projects-453ce85dd0e1
  • https://llunak.blogspot.com/2019/05/why-precompiled-headers-do-not-improve.html
  • https://www.bitsnbites.eu/faster-c-builds/


来源:https://stackoverflow.com/questions/34199127/every-c-header-in-a-project-as-a-precompiled-header

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!