-1

As I understand it a precompiled header is basically a dump of the compiler's state after processing the given header. When you compile a source file that includes a precompiled header, you trigger reloading that state from disk, which is cheaper than recomputing that state by actually reading/parsing/compiling code in the original header.

The obvious trade-off is changing any header included by the precompiled header requires regenerating the precompiled header which will trigger a full recompile of everything (since you usually include the precompiled header in every translation unit).

  • But what if I have lots of headers I never change, like all std C, C++ and POSIX headers, is there any reason to not include them all? I mostly care about incremental builds, so I'm not too concerned with the one-time cost of making the precompiled header.
  • If I'm using precompiled headers, is there no compile speed benefit to say making my own header is_same.hpp with just my own definition of std::is_same so that I avoid pulling in all of <type_traits> when I only need std::is_same? If bloating precompiled headers has no downside then there would be no benefit.

I can imagine that including more than you need could cause the compiler to have to do more work later, but I don't know how significant this is. For example, if the compiler state includes a hash table for symbols it may have more collisions (assuming a chain of buckets implementation). Or if I call an overloaded function it might have to consider more candidates. But I don't have any sense of if this is really a problem in practice, especially for std headers.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Joseph Garvin
  • 20,727
  • 18
  • 94
  • 165
  • 1
    Last I remember precompiled headers do not really work for templates, as there is no state that can be "dumped" to disk (except if you have explicit instantiations), so for something like `std::is_same` there won't be any performance gain. Precompiled headers would usually only include "regular" function and class declarations – UnholySheep Jun 13 '23 at 20:39
  • 4
    Measure it. The speed/size tradeoff might depend on your compiler. – HolyBlackCat Jun 13 '23 at 20:50
  • On reopening: this is a question of how compilers in practice work, there isn't anything opinionated about it. Either there is a downside to putting all the headers in or there isn't, I don't see any subjectivity here. – Joseph Garvin Jun 14 '23 at 02:21
  • @UnholySheep they can't actually do the code generation step for templates until they're instantiated, but there's a nontrivial amount of time spent parsing them as well (and sometimes the headers are huge, e.g. boost), and looking up everything they indirectly include must take some time, so I'd still expect a speed up – Joseph Garvin Jun 14 '23 at 02:23
  • @HolyBlackCat nobody is saying not to measure, but in practice there are only 3 C++ compilers anybody uses and one of them tries so hard to emulate the other it supports the same command line arguments. If anybody has already looked into this it would save a lot of effort. – Joseph Garvin Jun 14 '23 at 02:27
  • If you can use modules, they can be used as an alternatives of precompiled headers. (I suspect/wonder if modules were inspired by precompiled headers.) – Eljay Jun 14 '23 at 02:43
  • Generally speaking, I don't worry about precompiled headers much at all. My priority is to set up the build process/settings so the build is done *correctly*. I *might* then tweak to speed up incremental build times (options include precompiled headers, optimisation settings, use of component libraries, etc). But I mostly find that precompiled headers offer little benefit to justify the effort of setting them up. In largish projects, I usually find that careful organisation of headers (not including headers unnecessarily) has more impact on build times than precompiled headers. – Peter Jun 14 '23 at 06:00

1 Answers1

0

You typically do not include header files that change a lot in your precompiled header UNLESS IT IS USED BY MOST OF YOUR SOURCE FILES ANYWAY.

But if I have a .h that has its implementation .cpp, and it is needed by 2 of 99 client .cpp's, this header should NOT be included in the precompiled header, but just the 3 .cpp's (not implicitly in all 100 .cpp's via the precompiled header).

franji1
  • 3,088
  • 2
  • 23
  • 43
  • Ok but why? Is there actually a downside? – Joseph Garvin Jun 14 '23 at 02:24
  • Build time. If you have 5 "critical" headers included in 100 out of 120 cpp's, put those 5 in a pch. If you have 1 header that changes a lot, but is only needed by 5 cpp's, but you include THAT in your pch (which takes a LONG time to build since it has "every" header), you will be constantly rebuilding your pch and rebuilding all 100 cpps, but you only needed to recompile 5 cpp's. – franji1 Jun 14 '23 at 14:27