Patched rustc to fix why editing one generic method recompiles all 200 instantiations

So I was getting annoyed by slow incremental builds and ended up digging into rustc_monomorphize::partitioning in the compiler . Found something interesting - every monomorphization of a generic function gets pooled into one volatile CGU keyed on (module_def_id, volatile), type args completely ignored. So if you touch one method body in a generic-heavy crate, every single instantiation gets re-emitted. All of em. Even ones that have nothing to do with your change.

Wrote a patch that shards the volatile bucket by hash(symbol) % shard_count instead. One edit now only invalidates ~N/shard_count instantiations. Benchmarked on polars core, got ~0.96× incremental. Also stumbled on the fact that just setting -C codegen-units=16 (vs polars-core's default of 256) beat that result on its own, which I did not expect at all

Also tried one CGU per instantiation - that was 20× slower incremental because merge_codegen_units gets skipped in incremental mode. So it seems like bounded sharding is the move.

Benchmarked on polars-core. Patch alone: ~1% faster incremental. Full stack (patch + -Z threads=4 + cranelift + -C codegen-units=16) 0.521× cold, roughly 1.9× faster than baseline.

Configuration Cold Ratio
No Flag Baseline 62.27s 1x
Hashsharded patch 54.01s 0.868×
-Z threads=4 40.38s 0.739×
patch + threads4 (cu=256) 36.54s 0.587×
Cranelift (in-tree) 58.03s 0.932×
patch + threads4 + cranelift (cu=256) 38.20s 0.613×
patch + threads4 (cu=16) 33.77s 0.542×
patch + threads4 + cranelift (cu=16) 32.45s 0.521×
Note that the following test was done in an Intel Xeon with 4 cores and 15 GB available Ram

Patch adds -Z fine-grained-generic-cgus.

I thought this was interesting and wanted to share it

Blog post: I patched the Rust compiler because the build times were annoying me Patch and benchmarks: GitHub - Trigodil/Rust: A repo for compiler research for Rust · GitHub

3 Likes

"Column 1", "Column 2", "Column 3"?

Apologies! fixed it

1 Like

that's within the noise I think. Why all of this instead of making a pull request?

Surely 54/62 < 0.988?

Within the noise on incremental but 50% faster on from-scratch is actually pretty good, no?

1 Like

Overall - would be good, but here I see it in one very cherry picked scenario with changed flags and non default codegen.

1 Like

It scales with how many monomorphizations you have - smaller crates won't show it because the volatile bucket stays small. polars core is a stress test, picked it because I was informed it was the hardest case.

Yep, pretty much. The incremental is smaller but it compounds on every edit in a large generic heavy crate.

1 Like

Fixed it

I'm puzzled why you're posting here instead of making a PR. Was this vibe-coded and thus against the LLM policy or something?

1 Like

I have already created a PR concerning this fix, a separate repo was created for testing my own methodology and my notes of Rust compiler code to be thorough, although I will say because of the accusations of "AI" makes it un-preferable for me to contribute to the rust community further.

The rust community somewhat recently adopted an AI policy that allows AI for some cases (such as researching what to change) but is more restrictive (but not outright banning, depending on details) for the actual submitted content of the contributions themselves.

It appears that people are a bit unsure about what you used LLMs for and to what degree and are thus trying to figure that out. So I think the word "accusations" might be a bit strong at this point, "questioning" and "inquiry" might be more appropriate at this point.

7 Likes

The question makes sense. Why is this an internals post, when it could just be a Github PR?

Rust isn't against LLMs per se, but they can't be used to write code/comments/PR descripitons. It's a decent compromise seeing how LLM code might not be copyrightable, and thus accepting such code into codebase is a liability, and LLMs tend to overexplain to the nth degree.

3 Likes

A PR was actually opened to test this change. Here are the out-of-the-box perf. results on our benchmark suite: rustc_monomorphize: shard volatile generic CGU buckets to reduce incremental invalidation scope by Trigodil · Pull Request #162692 · rust-lang/rust · GitHub

5 Likes

I didn't even look at the change. It's just the only obvious reason to post on IRLO about it: if it's an amazing PR that's getting merged I figured you'd have linked that PR, so if it's not a PR the most typical reason these days is that it doesn't meet the PR bar because of LLM usage.

It gives me the same kind of vibes as the Bun blog posts complaining about Zig not taking their PRs :person_shrugging:

(Plus the blog credits claude and has a bunch of classic LLM-style phrasings so it's hardly unsurprising that people might wonder if there was "AI" usage.)

6 Likes