5 ms·
holy cow, I never would have thought in 2016 compiling a C++ program could be so slow that it makes it impossible for someone. Can you put numbers on these fig
by logicallee 10y ago
holy cow, I never would have thought in 2016 compiling a C++ program could be so slow that it makes it impossible for someone.
Can you put numbers on these figures? By "Unbearably slow" how many minutes (or hours) did you mean? Do you use a heavy desktop with a fast SSD and a lot of RAM?
Finally what is the total output program size (roughly). Like are we talking about an application that is in the gigabytes, like the complete Adobe suite or something?
I would like to know more information about how it's possible for this to happen. tell us as much as possible :)
Thanks!
- quinnftw 10y agoTo piggy back on this comment: what build system are you using? I've found that bazel has greatly reduced compile times, even when using boost and opencv.
- jlewallen 10y agoI just took a very quick look at Bazel and saw that Windows support is "Highly Experimental" which concerned me. I've been looking around in this space recently as I'm getting into C/C++ again (ARM uC stuff) and all three platforms are fairly important to me for what I'm doing. I'm a big Gradle fan and Bazel seems like a natural next step if it's not problematic.
- quinnftw 10y agoI develop solely in UNIX environments so I can't comment on its performance on windows, but it's fantastic on UNIX and very easy to write / configure.
- dom0 10y agoI have used qbs with great success. It's by far the fastest and most correct¹ build system for C++ that I've used so far, and it's configuration ain't so bad (tm). ¹ I used it in a couple projects and never had a single incorrect build. With most other build tools, be it CMake or Gradle, these happen regularly for me.
- lmm 10y agoI dug out some 5-year-old C++ code recently, about 20kloc. I was expecting it would compile instantly on modern hardware like my Surface Book. It's taking about 12 minutes to build on travis with some of the worst offenders disabled (the SWIG-generated bindings were particularly slow IIRC), and a local build feels like it takes longer: https://travis-ci.org/PembrokeNS/sakusen https://travis-ci.org/PembrokeNS/sakusen
- fauigerzigerk 10y agoI can't put numbers on it as the codebase no longer exists in that form, but I can tell you what I consider "unbearably slow". "Unbearably slow" is when the compiler takes too long for me to stay focused on a single task. So compile times in the minutes are a blow to my productivity. The machine is i7, 4 cores, 8G RAM, SSD. Definitely not as beefy as it should be. But my point isn't about how to optimize C++ compile times by adding more hardware. It's about the relative impact of "modern" C++ compared to traditional C++. There shouldn't be a disincentive to using modern libraries.
- logicallee 10y agoThanks!
- dibanez 10y agoAs others have mentioned, I've resorted to brute force (parallel compile using 16 physical cores, good SSD, 32GB RAM). I have a 20KLOC library that I wrote myself (very few templates), that takes 20 sec to compile in parallel, meaning in serial it would take about 5 min. Then there is a giant 3MLOC system I work with (much templating), that takes 20 min to compile in parallel (consuming 15GB RAM), meaning in serial it would take 6 hours. One can also see in this 3MLOC system that it is the last few small files that take the longest to compile, because they include much of the rest of the system as template code in headers.
- thechao 10y agoPreprocess your source 'cat' the results together; then, hand off to the compiler. On a 2015 MacBookPro I've seen upwards of 100kloc/s. Probably average 30--60kloc/s. With ccache my 5mloc code base takes as little as 300ms to do incremental compile & relink. Another thing is to rely on the preprocessor for code generation; then you're dealing with memory-speed elaboration of the AST, rather than reading off of disk.
- dibanez 10y agoI did the single file trick for the small library that I control, as a configure option. It definitely does help, 2X speedup in serial compile time typically. however, you lose the ability to compile in parallel, which with my hardware gives a 16X speedup, so for now parallel compiles are the winner.
- Joky 10y agoSomething smells with the structure of the project if a small change in a single file triggers a long rebuild. Including headers that define template should be "free", it is costly when you start instantiating all of them. There might be opportunity to restructure some part. Also precompiled-header or better: modules can help (not much with template instantiation though).
- dibanez 10y agoIn my parent comment are listed compile times from scratch, although there probably exist one or two files that would trigger similarly long rebuilds (included indirectly by most other files). If you change a random line of code, chances are the rebuild is quite limited. As others commented above, this actually scares people away from improving the core files.
- deong 10y agoSo the major component of a modern C++ application that contributes to long compile times is templates. In C and "older" C++, you're probably used to doing a particular style of separate compilation. You put your prototypes in header files, your implementations in cpp files, do the equivalent of `gcc -o somefile.o somefile.cpp` for every cpp file in your project. Each of those separate compilation stages has to include any referenced headers, but then it just compiles the code in that cpp file and writes an object file. At the end, you do one more step to link all the object files into a binary executable. This is fast and as parallelizable as the number of files you have. In C++ today, you're likely doing a lot with templates, and templates don't work this way. With templates, every compilation unit that references a template needs not just declarations from a header file -- it needs the complete source code for that template. You essentially have to #include the cpp files (through one mechanism or another). Simplifying a bit, that means that if you have a template defined in one file that is used by code in 25 other files, that template gets compiled 25 different times, and worse, you lose out on a lot of parallelism because by the time the compiler sees the code, the preprocessor has expanded the templates into one giant compilation unit that's going to be (slowly) compiled on one core. I just grabbed the code I wrote during my PhD thesis that was heavily template-based. It's tiny (about 15,000 lines of C++) and building it on this $3000 2015 Macbook Pro took about a minute, and clang++ used a bit over 800 MB of memory in the process. (https://github.com/deong/sls https://github.com/deong/sls if anyone cares to see the example). You certainly don't have to be building the Adobe suite to see compile times in the tens of minutes, and even moderate sized applications can put you into the hours. So much just depends on how the application is structured and written as opposed to only looking at size.