7 ms·
The reason compilation time is a problem is that compiler architecture is stuck in the 1970s, at least for systems programming languages. Compilers make you wai
by modeless 6y ago
The reason compilation time is a problem is that compiler architecture is stuck in the 1970s, at least for systems programming languages. Compilers make you wait while they repeat the same work over and over again, thousands of times. Trillions, if you count the work globally. How many times has <vector> been parsed over the years?
In a world where compiler architecture had actually advanced, you would download a precompiled binary alongside the source, identical to what you would have produced with a clean build, and that binary would be updated incrementally as you type code. If you made a change affecting a large part of the binary that couldn't be applied immediately, JIT techniques would be used to allow you to run and test the program anyway before it finished compiling.
There is no fundamental reason why anyone should ever have to wait for a compiler. And if you didn't have to wait, then it would free the compiler to spend potentially much more time doing optimizations, actually improving the final binary.
The zapcc project shows a bit of the potential for improvement in build times, though it's just scratching the surface. https://github.com/yrnkrn/zapcc https://github.com/yrnkrn/zapcc
- greggman3 6y agoYou lost me.... <vector> isn't executable code. It's generic instructions for how to generate new code given a type and at least in C++ that code is not and can not be shared because what is generated depends on the type itself.
- geocar 6y agoWhen a C++ compiler sees a statement like template<class T>... it updates its internal state to be able to recognise the constructions this statement is intended to enable. If you are able (somehow) to encapsulate this state, and save and load it faster than you can regenerate it, that’s a win. You can call it caching or memoisation or “incremental compilation” if you really enjoy that sort of thing, but this is such a basic concept that if you cannot understand it, you are going to have a lot of other problems.
- msla 6y ago> If you are able (somehow) to encapsulate this state, and save and load it faster than you can regenerate it, that’s a win. You can call it caching or memoisation or “incremental compilation” if you really enjoy that sort of thing, but this is such a basic concept that if you cannot understand it, you are going to have a lot of other problems. If you're going to be condescending like that, it would be nice if you could provide a concrete example of how to incrementally compile vector<T> in the general case in such a way that it's useful and reasonable to redistribute (that is, not tied to a specific architecture or compiler) instead of just waving your hands.
- geocar 6y agoYes, it would be nice for you if I did things for you for free, however it would not be nice for me. If you're writing a compiler and want specific advice about how to do this, by all means reach out via email and we'll work something out.
- msla 6y agoYou've yet to demonstrate you have the knowledge to do anything useful.
- cjfd 6y agoWell if vector<SomeType> is used in many cpp files it is compiled separately for each and every one of them and then the linker throws away these gigantic amounts of code duplication between the various object files. Also vector<shared_ptr<T>> really only needs to be compiled once for all variations of T. I don't think much or even anything is to be gained by having copies of this code in the executable for every T.
- pjmlp 6y agoOnly if not using external templates, or there is a missing declaration for SomeType.
- pas 6y agoA bit tangential, but - an ex-Scala core contributor's lament about why compilers have to be incremental: https://www.youtube.com/watch?v=TS1lpKBMkgg&t=42m https://www.youtube.com/watch?v=TS1lpKBMkgg&t=42m - a Rust core team member talking about responsive compilers: https://www.youtube.com/watch?v=N6b44kMS6OM https://www.youtube.com/watch?v=N6b44kMS6OM (basically the "low-level" implementation of the talk at the previous link)
- mrmonkeyman 6y agoYes, increase the complexity. That is usually what makes things more stable.
- api 6y agoThere's a lot of much lower hanging fruit. As you state: there is no reason the source has to be parsed from scratch every single time. A little memo-ization of intermediate data structures when the underlying source has not changed could go a long way. AFAIK Microsoft's toolchains do this but they don't do it well. It's a frequent source of headaches.
- benrbray 6y agoI think this is an area where practice has lagged quite far behind theory (for entirely reasonable practical reasons). I've seen quite a few papers relating to incremental parsing, compilation, etc. (e.g. [1,2]) but afaik very few build systems actually take advantage. [1] https://arxiv.org/abs/1312.0658 https://arxiv.org/abs/1312.0658 [2] https://blog.functorial.com/posts/2018-04-08-Incrementally-Improving-The-DOM.html https://blog.functorial.com/posts/2018-04-08-Incrementally-I...
- sumtechguy 6y agoIn some ways it can be the language fault too #define TURNONFEAT 1 #include <xyz.h> or #define TURNONFEAT 0 #include <xyz.h> That can create wildly different includes. The upcoming modules feature in C++ may change that. But unfortunately at this point we get to live with a recompile. Pre compiled headers took some of the sting out of it. It would be nice if they could say 'in this case at this point these flags existed and I used them I will hold onto that for this header'. That way you compile it once and the rest of the project can change things in and out. The pch way seems more 'i know I will not change the flags ever'. It was a good start. Maybe a new object type and it could even live on between compiles?
- mshockwave 6y agodunno why you got downvote, I thought your point was pretty legit. IMAO, we might even need to change common binary file formats (e.g. ELF, COFF) to accommodate this sort of feature
- sixstringtheory 6y agoIt seems to me that this is what linkers and static/dynamic libs are for. Why does it also then have to exist in the compiler? I suppose there's the problem of optimization across module boundaries, but if you solve that problem for compilers, might as well solve it for linkers. What you're describing sounds like my current best practice for developing iOS apps. I have multiple static libraries for separate logical code units that don't have to be recompiled when unrelated code is changed. This is for C, C++, ObjC and Swift. All iOS package managers have the option to download compiled binaries, as well.
- deleted 6y ago[deleted]
- amelius 6y agoOne problem is that Rust and C++ are not the best languages to build incremental compilers in, because these languages are not purely functional and on top of that the developer has to think about memory management all the time (in Rust the type-system limits the developer because of memory management which is more or less the same thing).
- secondcoming 6y agoThis argument makes no sense
- haimez 6y agoGPT-3
- dropit_sphere 6y agoI suspect "Please do not imply that another commenter is a neural net" will be one of the next items added to HN's guidelines.
- heavenlyblue 6y agoIt only doesn’t make sense because the author forgot to mention monads!
- qznc 6y agoSo the image-based persistence of Smalltalk and Common Lisp should be revived? I don't know what the downsides are.
- TeMPOraL 6y agoMy experience from Common Lisp development: The main downside is that it's easy to make your image out of sync with your code. That is, the state of the image during development (global variables and their values, functions, classes, environment settings) may end up different than what you'd have if you restarted the image and reloaded the code into it - which can lead to an unexpected cascade of bugs the next time you restart the image. In practice, you can guard against it with unit and integration tests, as well as just reading warnings the compiler gives you. Still, I don't think being image-based will help C++ as long as templates work the way they do - templates are code generators, so each time you change one, you have to recompile all its potential users. The way CL implementations tend to work, "building the image" is similar to C++'s linking process - i.e. whenever a Lisp file is compiled, the compilation output is cached, so it can be loaded quicker if the file didn't change. But if you change a widely-used macro, you end up having to recompile almost everything from scratch, which is similar to C++ and changes to header files.
- pjmlp 6y agoYes, that is what IDEs actually make with their AST databases, and what Energize C++ and VC++ v4.0 tried to bring into mainstream.
- doonesbury 6y agoMaybe making precompiled headers for all the boost/std stuff is needed? That is, it's around but not often used is my point.
- pjmlp 6y agoIt is used a lot in Windows compilers since Windows 3.0 days. Apparently other platforms never bothered that much into making work properly.
- mncharity 6y agoIn addition to improved local compilation, the constraint space for compiler design is also changed by cloud compilation. Distributed deterministic compilation like [1] would permit community-level caching. Distribution reduces the importance of peak computes - if prompt compilation requires a hundred cores, that could be ok. Community caching reduces the importance of worst-case performance - if some rich type analysis of a standard library takes days, that might be tolerable if it only needs to happen once. If optimization decisions can become a discrete things-on-the-side, like current execution traces for jit, then there's a new opportunity for human-compiler collaboration - "lay out the data in memory like so, when the cpu cache has this shape". I'm looking forward to the ferment of hobby languages starting to explore this new space. What would you do differently in designing a language, if the language community was served by a single giant instance of a compiler? How might that change the economics of language development? PLAAS? [1] https://github.com/StanfordSNR/gg https://github.com/StanfordSNR/gg Sort of checksums-and-argument-lists to make gcc deterministic, as for a cache, but farmed out so `make -j100` runs on amazon Lambda.
- deleted 6y ago[deleted]
- platz 6y agoalso sounds like Unison
- pjmlp 6y agoThe exception being Ada compilers, but then again most don't get to use them.
- klyrs 6y ago> and that binary would be updated incrementally as you type code Are you joking here? While I'm typing is the worst time to compile code. Much of the time, my code contains syntax errors because, for example, I'm in the middle of writing a line of code. I even write such "bad" code to the filesystem several times before deciding to compile, so I'd be quite annoyed if my computer churned on every file-save.
- salawat 6y agoYou seem to be suffering from magical thinking. Where does this blob come from, how is it that it can exist when you haven't written the code yet? I know that the Internet makes it seem as if data access is automatic and magic; however, fundamentally, computing is a physical process. Bits don't shuffle by magic, and they can't even be targeted for download to avoid compiling before compiling and checking the result against some sort of sample or list for whether or not the chunk of code already exists. No avoidance of compilation achieved. Compilation/interpretation is not something you're ever going to make go away unless you like programming with straight 0's and 1's.