C++ Compilation Speed
drdobbs.com
drdobbs.com
1. Templates
2. No pre-compiled headers
3. Bad header-organization
We have a reasonable sized desktop application 5 mb (release) / 19 mb (debug) that fully rebuilds in 10 s / 12 s (incremental < 2 s usually).
Yes, we have optimized using a RAM disk etc, but the main reason for the speed is No Templates and combining precompiled headers with efficient header-organization.
Some interesting links:
- http://gamesfromwithin.com/physical-structure-and-c-part-2-b...
- http://developers.sun.com/solaris/articles/CC_perf/content.h...
Because templates are basically automated code copy-paste, the compiler can more easily inline at compile-time. Unfortunately, it also translates to lots more compiled code, which means slower compile times and fatter binaries. Still, writing something like the STL library in C with the same performance characteristics would be much more difficult, if not impossible.
I'm not a C++ expert, but that's my understanding of things, at least.
Templates are more than copy/paste code, the compiler can make strong assumptions about the code path during the optimization phase because it's actual code.
It's not just a question of inlining calls but mainly a question of being able to remove branches altogether. Branches is the performance killer, remember?
Examples:
- with template specialization you can make "compile time" switches (horrible to reproduce with C + macros) - you can compute values at compile time (not quite possible in C + macros) - inlining permits copy elision (an optimization that doesn't exist in C since return by value is a non sequitur) - the CRTP is faster than an object with vtables because it avoids indirect calls - removing of dead branches, by inspecting the templates recursion, the compiler can determine which branches will never be taken and doesn't compile them - probably more!
Turbo Pascal took just a few seconds to compile the example (no surprises there), but Turbo C++ took several minutes. This was back in the 90's. It seems nothing has changed since then. Sad.
It doesn't have an automatic translator, but it's design does follow a rule of "If a piece of C code is dropped into a D compiler, either it compiles with the same semantics, or it doesn't compile."
BTW, Someone needs to fix the CSS for this text-entry box. Someone set the text color to black, but forgot to set the background color too. So on my light-on-dark system, I get Invisible-text-syndrome and have to edit in notepad and copy-paste into the text-box. Wheee!
However, building the library set and examples and tests is a one-time cost for the non-header-only libraries. And you don't need to compile the examples or the tests. Or the various debug-release combinations.
Plus, why wouldn't you cross-compile, anyway? I do lots of embedded sensor work and I wouldn't think of compiling anything directly on the hardware itself.
What it amounted to was debugging horrible compiler crashes, broken library behaviour and spending a long time deciphering huge template names. This caused me to hate C++ more than you can ever imagine. I swear whoever decided to stitch templates together in the way Boost does has never had to debug a development compiler, this broke almost every part of the toolchain.
Ugh.
I can't even imagine what it would be like on a 100hz computer.
D has been around for ages, during which time C++ usage has grown quite a lot, essentially at the expense of C and assembly.
First of all, I don't get the sense people are actually casting about for a C++ replacement. Secondly, garbage collection makes D a non-starter in probably over half the areas C++ is used.
C++ is now really for closer to the metal, where garbage collection is truly a non-starter and nobody cares that std::string is awkward because they don't use it.
Does anyone already know how the new standard libraries which they wrote do work?
Notice in particular that he says "Furthermore, you can use malloc() and free(), along with the rest of C's standard library, ..., without any overhead. Then, a D primitive called emplace allows you to construct objects at specified memory locations (a la C++'s placement new operator)".
The emplace function is in the std.conv library and is the basis for constructing objects outside of the control of the garbage collector.
My understanding is that most library functions do not care about whether you are using garbage collection or not. Library functions are usually written in a parameterized way such that you can use any appropriate object; so long as it has the right methods.
Take a look for example at the std.algorithm library: http://www.digitalmars.com/d/2.0/phobos/std_algorithm.html I don't think anything there cares whether you use garbage collection for your types or not.
(100 MHz is actually quite fast.)
The IncrediBuild guys have some success there, but you have to link from the .obj files, not .lib (okay if your project is setup like that, but also it does not work always).
We have found that heavy templates usage creates lots of symbols that point to memory get coalesced later, and this also slows down the linker.
- http://gamesfromwithin.com/how-incredible-is-incredibuild
My summary of the article (I haven't tried it myself): - can improve a full build compile time - will probably slow down incremental build compile time
But IB does not treat everytime in the .vcproj file as MS does. For example we used to link statically to certain libs, and later added them with the sourc code, and put dependancies in the .sln file. Well we forgot to remove the references, and guess what - MS ends up with one version, IB the other.
In our case IB was ignoring the .lib files, but taking directly the .obj files and linking with them (this has other side effects, for the globally initialized C++ objects).
But still it's time saver. We often have bad .pdb, .obj files produced, locked situations, etc.
We even use it for Makefile builds, but again such issues are popping out.
It's a clever system, that wraps the whole I/O and runs any process on a different machine, but all I/O is still done on the machine it's coming from... I wish that was somehow built in modern OS's.