Live data from Hacker News

C++ Headers are Expensive

virtuallyrandom.com

81–90 of 115 posts

Re: C++ Headers are Expensive

#81
Opera contributed jumbo build feature to Chromium. The idea is to feed to the compiler not the individual sources, but a file that includes many sources. This way common headers are compiled only once. The compilation time saving can be up to factor of 2 or more on a laptop.

The drawback is that sources from the jumbo can not be compiled in parallel. So if one has access to extremely parallel compilation farm, like developers at Google, it will slow down things.

Re: C++ Headers are Expensive

#82
post #4

I recommend three things for wrangling compile times in C++: precompiled headers, using forward headers when possible (e.g. ios_fwd and friends), and implementing an aggressive compiler firewall strategy when not. The compiler firewall strategy works fairly well in C++11 and even better in C++14. Create a public interface with minimal dependencies, and encapsulate the details for this interface in a pImpl (pointer to…

pImpl pattern is great for those who don’t care about performance but it’s inappropriate for most header libraries. You wouldn’t want a library that hides the implementation of std::vector for example. With a visible implementation the compiler compile e.g. operator[] down one x86 instruction. With a pImpl pattern it will be an indirect function call in all likelihood that will be hundreds of times slower. It can mak…

For cases when performance matters one can replace the members with a stab of the same size and alignment and cast the the stab to the real defition in the implementation.

Re: C++ Headers are Expensive

#83

Earlier quoted context omitted.

I don’t get the example, can you explain? What does this buy that you don’t have by simply putting the content of private.cpp into stack_pimpl.cpp? The data members are already in stack_pimpl.h (so nothing private or hidden about that) and the methods are already declared in both and implmented in both cpp files, so what are you buying over just putting the declarations in one header and implementation in one source…

So PIMPL is a compile firewall to keep the compile times and changes in one section from cascading and imacting your whole project with a recompile. It is not going to keep things secret as I can look at the binary and pick it apart. So with that, it keeps the data(state) in the public facing class. This allows one to keep everythign stack allocated instead of defaulting to the heap. So for something this is created…

Never mind, I was thinking wrong and neglected the ABI stability

Re: C++ Headers are Expensive

#84
post #81

Opera contributed jumbo build feature to Chromium. The idea is to feed to the compiler not the individual sources, but a file that includes many sources. This way common headers are compiled only once. The compilation time saving can be up to factor of 2 or more on a laptop. The drawback is that sources from the jumbo can not be compiled in parallel. So if one has access to extremely parallel compilation farm, like d…

This is also called "unity builds" and is used by Unreal Engine 4[1] and can definitely be used in parallel (eg. IncrediBuild).

[1] https://api.unrealengine.com/INT/Programming/UnrealBuildSyst...

Re: C++ Headers are Expensive

#85

Speaking about GNU C++ (and C), the headers are getting cheaper all the time compared to the brutally slow compilation. Recently, after a ten year absence of not using ccache , I was playing with it again. The speed-up from ccache you obtain today is quite a bit more more than a decade ago; I was amazed. ccache does not cache the result of preprocessing. Each time you build an object, ccache passes it through the pre…

> ccache does not cache the result of preprocessing

Only if you explicitly disable 'direct mode'.

Re: C++ Headers are Expensive

#86

Earlier quoted context omitted.

I don’t get the example, can you explain? What does this buy that you don’t have by simply putting the content of private.cpp into stack_pimpl.cpp? The data members are already in stack_pimpl.h (so nothing private or hidden about that) and the methods are already declared in both and implmented in both cpp files, so what are you buying over just putting the declarations in one header and implementation in one source…

So PIMPL is a compile firewall to keep the compile times and changes in one section from cascading and imacting your whole project with a recompile. It is not going to keep things secret as I can look at the binary and pick it apart. So with that, it keeps the data(state) in the public facing class. This allows one to keep everythign stack allocated instead of defaulting to the heap. So for something this is created…

[deleted]

Re: C++ Headers are Expensive

#87

Earlier quoted context omitted.

So PIMPL is a compile firewall to keep the compile times and changes in one section from cascading and imacting your whole project with a recompile. It is not going to keep things secret as I can look at the binary and pick it apart. So with that, it keeps the data(state) in the public facing class. This allows one to keep everythign stack allocated instead of defaulting to the heap. So for something this is created…

Never mind, I was thinking wrong and neglected the ABI stability

Please ignore the question I just posted regarding this topic. I only saw this comment after posting mine own.

Re: C++ Headers are Expensive

#88
post #79

Earlier quoted context omitted.

Java JIT-compiler inlines short method calls whenever possible. Though C++ compiler should be able to do the same.

And they do, when given PGO data, or when doing LTO.

Given this is a topic of slow c++ builds, mentioning LTCG should come with the caveat that it will absolutely destroy your compile times.

It's also not infallible and you might find it difficult to track a regression if introduced by someone silently breaking a heurestic in the optimiser.

Re: C++ Headers are Expensive

#89
post #31

Earlier quoted context omitted.

”It's just an extra indirection in the data member. It's cheap” That extra indirection often means a cache miss. That isn’t cheap. Accessing each item traversed through a pointer can easily halve program speed. Java tries hard to prevent the indirections (local objects may live in the stack, their memory layout need not follow what the source code say, objects may even only exist in cpu registers)

Hmm... if you were a horrible person you could declare a `char[n]` member instead of a pointer. Then you could placement-new the impl in the constructor, and static-assert that `sizeof(impl)>=n`... No more cache misses :-). :-(

When you need this, use aligned storage: https://en.cppreference.com/w/cpp/types/aligned_storage
Post reply on HN