The hidden compile-time cost of C++26 reflection
Posted by SuperV1234 4 days ago
Comments
Comment by ralferoo 17 hours ago
In 30 years of using C++ this is the first time I've ever come across "translation unit" being abbreviated to TU and it took a bit of effort to figure out what the author was trying to say. Not sure why they felt the need to abbreviate this when they explain PCH for instance, which is a far more commonly used term.
Thought I'd add the context here to help anyone else out.
Comment by pjmlp 17 hours ago
Comment by dataflow 13 hours ago
It's super common terminology for people around those spaces; they probably didn't even think about whether they should abbreviate it.
Comment by SuperV1234 10 hours ago
Comment by SuperV1234 10 hours ago
I've fully updated the article with new benchmarks.
A reader pointed out that the GCC 16 Docker container I originally used was built with internal compiler assertions enabled, skewing the data and unfairly penalizing GCC.
I've re-measured everything on a proper release build (Fedora 44), and the compile times are ~50% faster across the board.
The article now reflects the accurate numbers, and I've added an appendix showing the exact cost of the debug assertions.
I sincerely apologize for the oversight.
Comment by leni536 18 hours ago
<meta> is another question, it depends on string_view, vector, and possibly other parts. Maybe it's possible to make it leaner with more selective internal deps.
Comment by craftit 18 hours ago
Comment by SuperV1234 10 hours ago
Including <print> is still very heavy, but not as bad as before (from ~840ms to ~508ms)
Comment by surajrmal 15 hours ago
Comment by wjakob 17 hours ago
Comment by CoastalCoder 17 hours ago
I was somewhat horrified to discover that the STL ended up with a special role in the language spec. (IIRC, one of the tie-ins is initializer lists.)
IMHO it's far wiser to leave the standard library as something that isn't needed by the core language, and where users can (at least in principle) provide their own alternative implementation without needing compiler hacks.
I.e., those details are inherent in the definition of "library" in the C/C++ world.
Comment by jcranmer 13 hours ago
Comment by dataflow 13 hours ago
std::type_info? std::is_trivially_...?
Comment by direwolf20 16 hours ago
Comment by shadowgovt 14 hours ago
And given how much of the language's spec is "The behavior is undefined when combining these two features," it's not really a tome that is safely ignored.
At this point, I cannot recommend C++ on any new project that some external factor such as safety certification (which "solves" the problem by adding yet more pages of stuff a developer must not do that the language syntactically supports and compiles but generates garbage output) isn't forcing my hand on.
As of 2026 C has eclipsed C++ in popularity on the TIOBE index; anecdotally, roboticists I've chatted with have told me they prefer to write core functionality as C modules and then weld them together into high-level behavior with a terser scripting DSL over trying to write the whole thing in C++ and hoping there's no undefined behavior hidden in the cracks that multiple layers of linters, sanitizers, and auto-certifiers have missed.
Comment by HexDecOctBin 10 hours ago
What sins does STL commits that make it slow if templates themselves are not slow, and what kind of template code doesn't bloat compile times? In my experience, C++ libraries are usually one order of magnitude or more slower to compile than equivalent C ones, and I always chalked it upto the language.
Comment by r2vcap 17 hours ago
Comment by SuperV1234 10 hours ago
Not free, still need to audit, but much better than before. Sorry.
Comment by SuperV1234 4 days ago
I first created the module via:
g++ -std=c++26 -fmodules -freflection -fsearch-include-path -fmodule-only -c bits/std.cc
And then benchmarked with: hyperfine "g++ -std=c++26 -fmodules -freflection ./main.cpp"
The only "include" was import std;, nothing else.These are the results:
- Basic struct reflection: 352.8 ms
- Barry's AoS -> SoA example: 1.077 s
Compare that with PCH:
- Basic struct reflection: 208.7 ms
- Barry's AoS -> SoA example: 1.261 s
So PCH actually wins for just <meta>, and modules are not that much better than PCH for the larger example. Very disappointing.
Comment by SuperV1234 10 hours ago
Modules are actually not that bad with a proper version of GCC. The checking assertions absolutely crippled C++23 module performance in the original run:
Modules (Basic 1 type): from 352.8 ms to 279.5 ms (-73.3 ms) Modules (AoS Original): from 1,077.0 ms to 605.7 ms (-471.3 ms, ~43% faster)
Please check the update article for the new data.
Comment by dalvrosa 17 hours ago
Compilation speed is a huge part of productivity and enjoying writing C++
Comment by wffurr 16 hours ago
Comment by adev_ 13 hours ago
This talk just point that unique_ptr is not one of them due to the side effect of C++ move semantics being non destructive.
People that do not understand that should honestly stop to use it as an argument in favor of "there is no zero cost abstractions".
Comment by dataflow 13 hours ago
Comment by adev_ 13 hours ago
There is always a cost to abstraction, and that can take different form. In C++, it is often build time (and/or complexity). And Chandler, in his talk, is perfectly right about that.
But that does not change the validity of the C++ concept 'zero cost abstraction at *runtime*'. It is possible to get proper language abstractions while not sacrificing runtime performances.
I did get sharp on his comment because this talk is constantly posted by a specific C crowd that profoundly hate any form of abstraction and use it as a totem to justify terrible development practices.
If your language support zero cost abstraction and genericity, by the sake of god, use it... most of the time the impact in term compilation time is worth the benefits.
unique_ptr is a beautiful example of that btw.
Comment by dataflow 12 hours ago
Nobody is concluding you shouldn't write functions either.
Comment by adev_ 12 hours ago
> (and btw it's not just time that matters here)
My remark is still valid. Even considering memory space and cognitive complexity.
> even function calls are not always zero-cost. For multiple reasons, some of which differ across compilers more than others
Divergence about the support of inlining in compiler implementation have nothing to do with the debate here. Some idiosyncrasy about C++ argument passing and lifetime might causes a cost in some specific scenario, still that is specific to C++.
It still does invalid the concept of zero runtime cost for abstraction.
As much as people like to dismiss it, Stepanov was right all along.
> Nobody is concluding you shouldn't write functions either.
Then, you will be surprised to learn that some 'devs' actually recommend exactly this and write guideline that minimize the number of function written. They tend to be from the same crowd that the one was describing before.
Comment by jstimpfle 18 hours ago
Comment by SuperV1234 17 hours ago
Comment by JamesTRexx 16 hours ago
C++ is the opposite of simplicity and clarity in code.
Comment by kreco 17 hours ago
Comment by direwolf20 16 hours ago
Comment by jeffbee 15 hours ago
Comment by SuperV1234 10 hours ago
In many cases it's possible to only declare the template in the header, explicitly instantiate it with a bunch of types in a single TU, and just find those definitions via linker.
Comment by jeffbee 10 hours ago
Comment by zombot 16 hours ago
Comment by comandillos 14 hours ago