Earlier quoted context omitted.
Software still needs to be architected for performance from the start. Trying to micro optimize a loop before you know you need it what Knuth was saying to avoid.
Right. Much like avoiding pImpl because it might make a function call that occurs 0.001% of the time faster. That is the basis of the thread I was replying to. Understanding what you are optimizing FOR and where the most attention should be spent is the crux of Knuth's argument. Trying to be clever up-front is often counter-productive. There is nothing wrong with making some architectural decisions up front, but that…
C++ Headers are Expensive
51–60 of 115 posts
Re: C++ Headers are Expensive
#52Earlier quoted context omitted.
For instance, pulling in the STL for an interface header instead of encapsulating these details. :-) No one is claiming that we should ignore performance all together. But, understanding through profiling where performance issues are and designing toward a faster implementation is more important than trying to inline definitions up front.
Do you also write all your functions to pass large inputs by value until a profiler says you can pass a const reference? Some implementation details are so well understood that you really don't need a profiler to do what is probably the right thing by default.
No, but neither do I pass types that fit in a native integer by const reference because copies should be avoided at all costs. There is always a tradeoff.
> Some implementation details are so well understood that you really don't need a profiler to do what is probably the right thing by default.
Avoiding any and all indirection at all costs is not one of these.
The pImpl pattern, much like virtual methods, function pointers, etc., are each tools. Indirection is a trade-off that is either worth the expense in cache misses or is not. The cost is not so cut and dried as others in the thread have assumed.
Re: C++ Headers are Expensive
#53Earlier quoted context omitted.
Right. Much like avoiding pImpl because it might make a function call that occurs 0.001% of the time faster. That is the basis of the thread I was replying to. Understanding what you are optimizing FOR and where the most attention should be spent is the crux of Knuth's argument. Trying to be clever up-front is often counter-productive. There is nothing wrong with making some architectural decisions up front, but that…
Well pImpl itself could be a premature optimization.
However, if compilation times have gotten painful enough that we need to examine performance improvements to our headers, the pImpl pattern is one of many tools in the toolbox. So are forward headers and other compiler firewall techniques.
Re: C++ Headers are Expensive
#54Isn't this the reason precompiled headers are a thing?
Yes, I was measuring time to rebuild everything (including the PCH) from scratch. So it's probable that incremental compilation is slightly faster using PCH, it's just not nearly as much as I was hoping for.
Re: C++ Headers are Expensive
#55Earlier 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 :-). :-(
Re: C++ Headers are Expensive
#56Re: C++ Headers are Expensive
#57Earlier 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 :-). :-(
Re: C++ Headers are Expensive
#58Speaking 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…
Ancient wisdom was that more than 50% of the time is spent compiling the headers, after they become a part of your translation unit after preprocessing. I don't see why preprocessing itself would ever be singled out, given that it's comparatively much simpler than actual compilation.
Re: C++ Headers are Expensive
#59Isn't this the reason precompiled headers are a thing?
It is, but precompiled headers are a pain in the a… (often less so than not using them, but still) They force programmers to tell the compiler what intermediate result to cache. Finding the best intermediate result to cache is a black art, and that set will change when your source code grows, forcing you to either accept that your precompiled headers may not help that much, or to spend large amounts of time optimizin…
Simply put - if it's #include , it goes into the precompiled header. Otherwise, it goes directly into the source.
The downside of this is that every time you add a new dependency, the entire project is rebuilt, since the change in your precompiled header affects all translation units. But adding dependencies is rare, and changing code and rebuilding is far more common.
Re: C++ Headers are Expensive
#60Earlier quoted context omitted.
Another option is something like pimp but keep the state in the public class. Now you get stack allocation but the private part is still private and firewalling all the other headers and details not needed for the public interface. Just pass this to the private methods. Edit: Something like https://github.com/beached/stack_pimpl
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 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 en mass(A vector of them) or created and destroyed often, this is a runtime win.
What it does is have a proxy that mirrors the public interface that is passed the this pointer. That proxy a friend class. Because only the proxies header(in this case private.h which I should probably rename firewalled.h) has static members that mirror the public members on the public class that limits the interaction between your classes users and it's implementation, as it is also with unique_ptr(or whatever pointer/heap way) based PIMPL designs. So changes in private.cpp that does all the work are only reflected in that one file. This file also brings in the heavy templates or algorithm code that may have large compile times.