I have a very large c++ project and I'm trying to decrease build times. I've been religious about forward declaring and only including files which are used. However I have many preprocessor defines which are setup in the project files (ie not in cpp or header files) so that I can keep them all in a central location for my different build configurations. Is it possible that this could increase build times? Would moving the preprocessor defines to a header file so they will only be included where needed speedup the build time?

It seems like the build time would be faster if the preprocessor didn't need to scan and replace the defines for files that don't use any of them, but I'm not sure if it's worth the effort.

  • have you profiled the difference? – user40980 Jun 20 '13 at 0:05
  • 1
    in project file you mean like the -D option? – ratchet freak Jun 20 '13 at 0:37
  • @ratchet freak: Yes -D option for the compiler is what I mean. – RaWz Jun 20 '13 at 1:30
  • @michaelT: I have not profiled the difference. I wanted to get the opinions of others to determine if it was worth the effort. – RaWz Jun 20 '13 at 1:32

Unused macros that are specified on the command line of the compiler (through -D options) should not have any measurable impact on build times. The parsing of command line arguments is insignificant compared to the time it takes to compile even a smallish source file and the compiler can't skip the preprocessing step anyway because there will invariably be some #include-s to process and some macros to expand.

  • I've never looked into the internals of a preprocessor, but I imagine that it would first concatenate the includes and then string replace any defines. Although the time it takes to replace the defines might be insignificant compared to the compile time when the preprocessor has to do that for thousands of files that it doesn't need to, I would think that in some cases, depending on the LOC, it could have a significant impact. However, if there will always be at least one define that needs to be replaced the you make a good point that the define replacement step cannot be skipped. – RaWz Jun 20 '13 at 12:45
  • @RaWz: C and C++ (including the preprocessor stuff) are defined in such a way that it is possible to compile a source file in a single pass, meaning that every line of the file gets read only once. There is no need to perform #include expansion and macro substitution in multiple passes. – Bart van Ingen Schenau Jun 20 '13 at 13:05

My experience with build time is pretty simple: it's about linear with number of translation units. So if you want to reduce it, either paste some sources together, or do "unity compile". the latter means you #include groups of .cpp files, and compile that instead of the originals. Certainly it means static symbols get shared. For variables it's not that hard to detect, for functions might be trickier.

A source that may be just 100 LOC, or a few thousands at most normally picks up 100k to 1M LOC in included headers. What explains the figures.

Other things to explore are obviously precompiled headers and parallel builds. With PCH rules change significantly, fight to not include stuff and stick to forwards can be dropped.

I doubt the #defines themselves would cause any measurable impact.

Certainly all depends much on what compiler you use.

  • The application is compiled for multiple platforms and compiled using gcc, mingw, and vs2008. – RaWz Jun 20 '13 at 1:38
  • I never heard of combining cpp files using #include, that's an interesting technique. I think using precompiled headers is a good idea. – RaWz Jun 20 '13 at 1:58

Your Answer

