4 ms·
I like to think of a compiler as a virtual machine whose instructions are the tokens in your code, and whose output is object code. Taken that way, you can for
by thechao 5y ago
I like to think of a compiler as a virtual machine whose instructions are the tokens in your code, and whose output is object code. Taken that way, you can for sure optimize the input program (your C++) to execute faster on the interpreter (the compiler). Understanding how the language (any language with such features) is implemented lets you stray away from the slow parts.
For instance, in C, every function has a unique, global name. That means the implementation in the compiler can be a hash-table from string to implementation. C++ allows function overloading; now, our 'hash table' is a much more complicated thing: first, we must consider every function in the overload set no matter what; second, we must pick which function is "best" — usually through some complicated unification scheme. In all, this means that C function lookup is O(1) (probabilistic), whereas C++ function lookup is O(n) at best, but with unification it might be O(n^2) or O(n^3). I've seen slow compiling code with hundreds of identically named functions.
Templates are slow for two reasons: (1) they get shared via header files, so they get reparsed over-and-over-and-over; and, (2) they're implemented with a stringy interpreter whose job is to instantiate copies of the code. This is distinctly slower than macro expansion; generally, macro instantiation is of code and so occurs in source files — only requiring a single parse; and, also, there's just string-replacement, not an interpreter.
But ... here's the thing. You can make your C++ code compile fast by simply not using slow paths through the compiler.
- WalterBright 5y ago> I've seen slow compiling code with hundreds of identically named functions. I sometimes think I've seen everything programmers do, and then something like this pops up. > You can make your C++ code compile fast by simply not using slow paths through the compiler. D is fast to compile because it sidesteps or redesigns features that make for slow compilation.
- moonchild 5y agoD is horribly slow to compile template-heavy code for exactly the same reasons as c++. And it encourages lots of monomorphization in e.g. ranges. The enhanced introspection and reflection (and CTFE) capabilities coupled with mixins also encourage code that is very slow to compile.
- WalterBright 5y agoNot really. For example, D templates are never parsed more than once. The trouble is, people use templates more and more until they hit compile speed problems. I'd argue that this limit is much higher in D, but the end result is similar.
- munificent 5y agoJust like nature abhors a vacuum, my experience is that regardless of how fast your compiler is, user programs will grow to until they reach a point where they are annoyingly slow to compile.
- mpweiher 5y agoSolution: drastically lower your annoyance threshold. You'll be more grumpy but much more productive. I get antsy when my test suite takes more than a second or so.
- mhh__ 5y agoAs opposed to encouraging manually written code which is also not free to compile but has the added benefit of potentially introducing bugs?
- moonchild 5y agoAs opposed to encouraging polymorphic code (a la haskell, java), which is fast to compile and provides better type safety. (Yes, I know neither javac nor ghci are particularly fast, but that doesn't detract from the general point.)
- fm77 5y agoWalter, I am sorry, completely off-topic… but I have to ask - and you don’t have to answer ;-) …is that you? https://archive.org/details/byte-magazine-1988-09/page/n148/mode/1up https://archive.org/details/byte-magazine-1988-09/page/n148/...
- Zababa 5y agoThere's a (french) wikipedia page about Zortech https://fr.wikipedia.org/wiki/Zortech https://fr.wikipedia.org/wiki/Zortech
- thechao 5y agoIf I told you the first attempt was several million identically named functions, split across several hundred files, and the compile and link times were ~72 hours on a distributed build would you be happier? A single templated function & a few n*100kloc macros later, and I got the compile time down to ~1s on a crappy laptop. Macros are 'fast paths' through compilers — they copy structures in memory, rather than going through the entire disk->lex->parse chain.
- woodruffw 5y ago> For instance, in C, every function has a unique, global name. That means the implementation in the compiler can be a hash-table from string to implementation. If only we were so lucky ;). Symbols are not unique across the translation unit boundary, which is why we have C’s mess of fake namespace hacks. Even `static` doesn’t save the linker from doing extra work —- check out the locally bound symbols in one of your ELFs sometime! You’ll probably find some duplicates.
- zozbot234 5y ago> You can make your C++ code compile fast by simply not using slow paths through the compiler. Rust is also working on making this easier, BTW. There's still quite a bit of excess monomorphization going on when using generic code, but better support for const: in generics should ultimately obviate this.