8 ms·
Is it an unpopular opinion to say 75% of “a lot” is still “a lot”, plus now you have to keep track of the knobs and constantly monitor for and be conscious abou
by klabb3 3y ago
Is it an unpopular opinion to say 75% of “a lot” is still “a lot”, plus now you have to keep track of the knobs and constantly monitor for and be conscious about not wrecking build times as you’re maintaining and developing.
I’ve found in 10+ years of software development that speed of iteration cycle is highly correlated with productivity. Compile times is not the only input into this cycle time, but it’s a big one, and importantly, it’s within the control of the language tooling itself to solve. The human idle attention time of 1-2 seconds should be the gold standard to strive for, even if not always achievable.
There seems to be quite a bit of cope around Rust build times in the community, which was natural a few years ago (a lot of people used to “blame” llvm, but it doesn’t seem to be as big of a culprit) but things are different now, no? Given the maturity, growing ecosystem and corporate investment, I would expect incremental build speedup to be prioritized, and steadily improving. But clearly it isn’t moving very fast in that direction. So why not?
- IshKebab 3y ago> I’ve found in 10+ years of software development that speed of iteration cycle is highly correlated with productivity. I agree, though in practice with many Rust programs that iteration cycle is actually not "edit, compile, run", it's "edit, save, wait for rust-analyzer to update" which is generally much quicker (even if it is sometimes still a little slow). In most cases, Rust's very strong type system means you spend a lot less time actually running your program. There are definitely exceptions though. E.g. if you're making a web app and editing CSS or whatever then the Rust compiler isn't going to tell you if you've got the colour wrong. > a lot of people used to “blame” llvm, but it doesn’t seem to be as big of a culprit It still is; there was a post here really recently where someone broke down the time spent in various phases. LLVM is still the vast majority, though apparently that is partly due to Rust generating a lot of work for it. > I would expect incremental build speedup to be prioritized, and steadily improving. It is. > But clearly it isn’t moving very fast in that direction. So why not? Because Rust's unit of compilation (a crate) is very large. In C/C++ it's a single file.
- rockwotj 3y ago> I agree, though in practice with many Rust programs that iteration cycle is actually not "edit, compile, run", it's "edit, save, wait for rust-analyzer to update" which is generally much quicker (even if it is sometimes still a little slow). This is one area that I think Dart did a good job on. They support both a JIT (I am not sure if it’s tiered) and AOT modes of compiling, the JIT targeted for development and AOT for production. This is the ultimate extreme of optimizing for both use cases, obviously it’s a ton of work, but I would love more languages to be like this. (I believe the JIT mode works directly on the source so there isn't an intermediate compilation step like Java, but it’s been a few years since I’ve used Dart) [1]: https://dart.dev/overview#native-platform https://dart.dev/overview#native-platform
- IshKebab 3y agoI agree. And Dart's VSCode extension is suspiciously fast. Like it accurately finds compile errors in easily 100ms. I don't know what they've done so differently to pretty much every other system, where you're talking ~1-2s typically. It's very nice though.
- pjmlp 3y agoThis is the best of both worlds, that traces back to Lisp and BASIC environments. Have all variants available and allow the devs to pick the right one for their current workflow. Java, .NET, Eiffel, Common Lisp, Scheme, C++ (via stuff like ROOT and Live++, VC++ hot reload isn't that full proof), OCaml, Haskel, are all examples of these mixed tooling approach.
- physicsguy 3y agoIt is a single file, but when you include header files which get dropped in they can get to many hundreds of thousands of lines of code in practice per corresponding .o file.
- saurik 3y agoBut the level of parallelism possible is downright insane with C++ because of this property... once, out of anger at my build time on something I was working on back in 2016/2017, I set up a AWS Lambda as a compilation server (fully generic: all it had was my toolchain, not the code in question or even the build scripts) for something akin to ccache and successfully managed to build my project with a pipeline (I use that word as I was still doing the preprocessing locally) of at least a hundred simultaneous jobs: good luck ever pulling that off with Rust. It is also generally very easy to break apart any file or decouple any header files using various techniques that don't affect your project layout or require any mental maintenance once done. In contrast, with Rust, you have to essentially refactor what your project even "means" to pull that off as you now need to be juggling a ton of microcrates (and then it seems like there is some inherent crate overhead so this becomes a painful tradeoff plane you need to optimize; compilation units have to become degenerated small before that matters in C++). And, even then, the remaining slowest file in my insanely complex C++ project does tend to take a ridiculously long time to build (I have a 30-60 second long compile for one small component) and I have run out of low-hanging fruit; but, I honestly hardly ever actually have to build it: the coupling of header files is massively overstated as when you are in a tight build/update cycle you are generally modifying a single function in a source code file, not changing some header file of basic data types that will affect the code generation of literally the entire rest of the project. Like, I get it: thinking about code as a merged set of linear forward passes is sometimes annoying, but it doesn't just enable massive gains in compile time... it also encourages more legitimate coupling between components as circular dependencies require extra code and upkeep for prototypes and that's good because circular dependencies are bad. Rust thereby is doing something that frankly feels super awkward: it is elevating behavior that frankly makes more sense only within a single file or at best a single object to a project organizational unit, which suddenly makes this all seem much more complicated to handle correctly.
- deleted 3y ago[deleted]
- nindalf 3y ago> Is it an unpopular opinion to say 75% of “a lot” is still “a lot” I don’t know if it’s unpopular, but it may be inaccurate. OP claims that they improved by 75%, so you probably meant “25% of a lot is still a lot”. > I would expect incremental build speedup to be prioritized, and steadily improving. But clearly it isn’t moving very fast in that direction. So why not? Is this assessment based on something? For what it’s worth, people have been working on it for years, with varying approaches and levels of success. The recent spate of articles you’ve seen is precisely because these approaches are bearing fruit. Several folks have worked on making a previously single threaded frontend multithreaded, others have added an option to swap the LLVM backend out for a much faster one (cranelift), and yet others are working on moving to a faster linker by default. The net gain from all of these once they land could be as much as 30–50%, depending on the project, mode of compilation (clean or incremental) and hardware (single/multiple cores). That is a pretty fantastic improvement, considering the whole year improvements in the last 4 years have been 7%, 17%, 13% and 15%, for an overall speed gain of 37%. If all of this doesn’t sound impressive, I’d encourage you to read nnethercote’s annual reports which explain how much effort went into making compile times faster. 2023’s report - https://nnethercote.github.io/2024/03/06/how-to-speed-up-the-rust-compiler-in-march-2024.html https://nnethercote.github.io/2024/03/06/how-to-speed-up-the... Ultimately, all of these improvements might not be enough for the people who need HMR to be productive. That’s possible. But the idea isn’t to get to a point where every line of code written in the world is Rust. There’s plenty of Rust development happening today. When the compile times drop as hoped, more people join and that grows the ecosystem.
- dist1ll 3y agoI have a feeling many of the common multithreading optimizations carry the same flaw as incremental compilation: they give you good speed-ups in the short term, but potentially mask deeply flawed architectural decisions. Essentially improving perf by digging yourself into a deeper grave.
- klabb3 3y ago> you probably meant “25% of a lot is still a lot” Yeah exactly. This was afaik a fairy small sized application (where the majority was probably framework code) which went from 20s to 5s for incremental compilation on a very beefy desktop rig. Those absolute numbers are important to grok the situation. > That is a pretty fantastic improvement, considering the whole year improvements in the last 4 years have been 7%, 17%, 13% and 15%, for an overall speed gain of 37%. > If all of this doesn’t sound impressive, I’d encourage you to read nnethercote’s annual reports which explain how much effort went into making compile times faster It’s not at all that it’s unimpressive. It’s abundantly clear that extremely bright minds are putting a ton of effort into it, consistently and over time. I’ve worked personally with some of these people and they are insanely talented and knowledgeable… Which is precisely why I’m concerned that we’re not seeing the big boosts that comes with picking low hanging fruit, perhaps there isn’t any left. Optimization tends to yield lower results over time (although the recent advances are great to see and I wish it continues). From the outside though, it appears like either inherent constraints that limit how far you can go, or at least initial compiler design reasons that would be cost-prohibitive to change.