← Back to context

Comment by yearolinuxdsktp

3 days ago

It’s insane. 45 minutes to build debug from scratch. Linking is super slow even in debug and that’s without LTO.

Incremental compilation is not cleaned up. Older deps pile up and don’t get cleaned.

Run out of disk space? Oh it’s just the 200+ GB codex-rs target folder.

Forget about doing worktrees.

Rust has a lot of work to do.

If there's a project that takes 45 minutes to produce a debug build from scratch, that's not a Rust problem, that's a them problem.

Let's compare. I just checked out ripgrep and built it and all its dependencies from scratch. Total time to produce a debug build: 6.92 seconds. This is inside a 16GB VM on a random Linux laptop (on battery); no beefy hardware here.

Let's try something beefier. I just checked out uutils (an implementation of coreutils) and built it from scratch. Total time to produce debug builds, for eighty binaries and all their dependencies: 30.26 seconds.

Let's try something beefier. I just checked out Servo, an entire browser engine, and built it and all its dependencies from scratch. Total time to build and link its one-thousand one-hundred and ten compilation units (along with its infamously huge and serial servo-script bottleneck) into a binary: 4 minutes and 38 seconds.

If Codex takes 45 minutes to build from scratch, that's an indictment of OpenAI and their development processes.

  • Arguably it is a rust problem. Rust can be improved to reduce the need to do as much manual maintenance of crates dynamics to allow for faster build times. The "you're holding it wrong" answer is not a good perspective to apply and I am surprised to see a prominent member of the rust community using it.

    • No, one can write pathological code in any language. I welcome efforts to improve the performance of the Rust compiler, but nobody is served by optimizing for degenerate use cases to the detriment of legitimate use cases. It is, in fact, possible to hold it wrong; this isn't blithe dismissiveness, but rather an accurate statement of reality, and pretending otherwise doesn't lead to a better language.

> Incremental compilation is not cleaned up. Older deps pile up and don’t get cleaned.

This is one of those problems that’s both huge/important, and probably impossible to solve. It bites me all the time, I have a measly 1TB nvme disk and I basically have to wipe my target directory and docker build cache (I have a shared cargo cache volume across builds) every other day. I’ve had this workstation for 2.5 years now and I’m honestly worried about nand endurance coming to bite me soon.

How would one even solve this? When do you know a cache entry won’t be used any more? Trace back provenance of artifacts to their sources, and if the mtimes have been bumped just delete the artifacts? It’s not like resetting source files to older mtimes is a good idea anyway…

  • I disagree it’s impossible to solve. Huge C++ projects don’t have continuously growing build directories and can still compile incrementally correctly.

    • That’s because they overwrite the old artifacts with new ones every time, which has its own problems: you could end up reusing stale artifacts if your compiler version changes, or if different compiler args are used for the same artifact, and a bunch of other stuff. Rust computes a digest of all the relevant build environment settings that may need a different artifact to be built, and uses that digest in the file name. That means you basically never have issues like “oh crap the incremental build broke, do a clean build instead”. (Amongst a whole lot of other benefits I’m sure.)

      But this technique errs on the side of not using invalid artifacts, at the cost of not having a good system for expiring them. To maintain the goal of never having to worry about when to require a clean rebuild, solving cleaning of stale artifacts becomes a much harder problem.

I've abandoned zig for rust. I expected to be annoyed by rust build times, but so far it's been quite good for my needs. To the contrary it has not been any impediment even when prost etc all drag in many deps from a cold build.

The zig compiler apart from a couple of cross build or linker issues is darn good. Switch to rust is a function of library support, private struct fields. Rust itself is better organized and far better documented compared to zig.

However, rust has got to get their allocators for container support straightened out soon. I do SAAS for fintech and low level packet transports. Both benefit greatly with allocators custom designed for job at hand.

45 mins strikes me as something else is amiss ...

  • > However, rust has got to get their allocators for container support straightened out soon

    Good news: https://github.com/rust-lang/rust/pull/156882

    The allocator API has been stabilized, to be released in Rust 1.100 in November. (Though only Vec and Box will support custom allocators immediately; the rest of the standard library collections are coming later.)

> Linking is super slow even in debug

Linking is normally slower in debug btw (because of the debug info)

  • Use the split-debuginfo setting in your Cargo.toml to have the DWARF bypass the linker (on Linux, YMMV on other platforms).