Don't ever try C++. I work on a medium-sized low-level C++ application, and every time we need to compile from scratch it takes over two hours on a single core. Even with distributing the compilation out across over a hundred cores the fastest it can get down to is around 20 minutes.
Perhaps they're changing some fundamentals of the codebase and (unsurprisingly) the compiler seems slower than you might expect.
Pimpl is more for reducing how much you have to change headers forcing a recompile during development. It's also really handy for keeping binary compatibility with published dynamic libraries so that you don't have to recompile dependants.
- "module" system based around textual inclusion of header file: essentially the compiler duplicates a lot of effort, reading the same files over and over for each translation unit, and you can't avoid the cost because of the interaction with text macros. That said, C++20 offers a solution through its new module system; it will be interesting to see how much of an improvement this will bring.
- complicated parser requiring contextual information (i.e. information from typing and analysis phases) in order to distinguish between, say, a class object instantiation and function forward declaration (the notorious most vexing parse). Most other languages learned from the syntax mistakes of C++, but C++ had a clear mandate to not break existing C code, so it had no choice but to build what existed.
- C++ template system revolves around a kind of syntactic substitution, where you have a template expression with some type variable, and at the template instantiation site (i.e. every call, not at the definition) you you essentially do template argument deduction yielding concrete type bindings for the type variables, and then your next step is the transform the AST with the template expressions into concrete types, functions, etc. This involves a lot of tree transformations which can be expensive. I think with other languages this is less of a problem in part because the type checking is done at the definition site, rather than at call site. Here again C++ concepts were introduced to address this issue, but as always in C++, it's not all milk and honey.
Formula known for years: keep it simple, minimal template (ab)use and know what you are putting in .h/.cpp files. Cramming everything into headers hoping compiler will inline stuff is a bed time story. Also, your build system will be grateful knowing that every compilation unit is independent as possible; it will take less time to calculate dependencies and will easily distribute compilation across cores, if requested.
I just compiled around 240k lines of scala split over around 200 gradle subprojects with gradle 6.5rc1 and scalac 2.12.11. Limited to 10 gradle workers. Took 4 minutes without the gradle build cache enabled.
Also gradle 6.5 fixes a scala compilation performance regression that was introduced in gradle 6: https://github.com/gradle/gradle/issues/12591
https://www.lihaoyi.com/post/SowhatswrongwithSBT.html
https://engineering.linkedin.com/blog/2018/07/how-we-improve...