How expensive it is for the compiler to process an

2020-03-31 08:41发布

问题:

To speed up the compilation of a large source file does it make more sense to prune back the sheer number of headers used in a translation unit, or does the cost of compiling code far outweigh the time it takes to process-out an include-guarded header?

If the latter is true an engineering effort would be better spent creating more, lightweight headers instead of less.

So how long does it take for a modern compiler to handle a header that is effectively include-guarded out? At what point would the inclusion of such headers become a hit on compilation performance?

(related to this question)

回答1:

I read an FAQ about this the other day... first off, write the correct headers, i.e. include all headers that you use and don't depend on undocumented dependencies (which may and will change).

Second, compilers usually recognize include guards these days, so they're fairly efficient. However, you still need to open a lot of files, which may become a burden in large projects. One suggestion was to do this:

Header file:

// file.hpp

#ifndef H_FILE
#define H_FILE

/* ... */

#endif

Now to use the header in your source file, add an extra #ifndef:

// source.cpp

#ifndef H_FILE
#  include <file.hpp>
#endif

It'll be noisier in the source file, and you require predictable include guard names, but you could potentially avoid a lot of include-directives like that.



回答2:

Assuming C/C++, simple recompilation of header files scales non-linearly for a large system (hundreds of files), so if compilation performance is an issue, it is very likely down to that. At least unless you are trying to compile a million line source file on a 1980s era PC...

Pre-compiled headers are available for most compilers, but generally take specific configuration and management to work on non system-headers, which not every project does.

See for example:

http://www.cygnus-software.com/papers/precompiledheaders.html

'Build time on my project is now 15% of what it was before!'

Beyond that, you need to look at the techniques in:

http://www.amazon.com/exec/obidos/ASIN/0201633620/qid%3D990165010/002-0139320-7720029

Or split the system into multiple parts with clean, non-header-based interfaces between them, say .NET components.



回答3:

The answer:

It can be very expensive!

I found an article where someone had done some testing of the very issue addressed here, and am astonished to find you can increase your compilation time under MSVC by at least an order of magnitude if you write your include guards properly:

http://www.bobarcher.org/software/include/index.html

The most astonishing line from the results is that a test file compiled under MSVC 2008 goes from 5.48s to 0.13s given the right include guard methodology.