Skip to content

perf: Provide ThinMap, a map that uses ThinVec when the length is small - #23228

Open
ChayimFriedman2 wants to merge 1 commit into
rust-lang:masterfrom
ChayimFriedman2:shrink-def-map
Open

perf: Provide ThinMap, a map that uses ThinVec when the length is small#23228
ChayimFriedman2 wants to merge 1 commit into
rust-lang:masterfrom
ChayimFriedman2:shrink-def-map

Conversation

@ChayimFriedman2

@ChayimFriedman2 ChayimFriedman2 commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

It saves memory by being only one machine word inline and compact (no extra capacity) outline, while also being even faster if the length is commonly small because linear search is faster for small lengths.

When measuring analysis-stats, this saves 40mb on self, 77mb on buck2 and 142mb on omicron. It's also faster: 3ginstructions saved on self and buck2, and 30ginstructions on omicron (walltime is too noisy). The memory effect is also likely to appear in IDE scenarios almost as well, because a major part is def maps, and I speculate that unnamed consts also play a role (because the amount of almost-empty expression stores seem too high for real bodies).

Not all maps were changed to use this, only those that measurements show are commonly small. The threshold was at least ~95% of the maps of this kind fitting into the thin schema (that is, have at most 10 elements).

I also switched some IndexMaps to HashMaps where I believe the order does not matter.

I made ThinMap generic over the map type to support both HashMap and IndexMap. However at the end the number of IndexMaps was very small. I still can support both, but I wonder if I should or just make it non-generic and simplify the code. Currently I left it neither supporting IndexMaps nor removing the trait; will appreciate opinions.

ThinMap (and ThinSet) could very well be in their own crate, I just found no suitable crate on crates.io (also, the API isn't polished enough for an external crate).

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 25, 2026
@rustbot

This comment has been minimized.

It saves memory by being only one machine word inline and compact (no extra capacity) outline, while also being even faster if the length is commonly small because linear search is faster for small lengths.

When measuring `analysis-stats`, this saves 40mb on self, 77mb on buck2 and 142mb on omicron. It's also *faster*:  3ginstructions saved on self and buck2, and 30ginstructions on omicron (walltime is too noisy). The memory effect is also likely to appear in IDE scenarios almost as well, because a major part is def maps, and I speculate that unnamed consts also play a role (because the amount of almost-empty expression stores seem too high for real bodies).

Not all maps were changed to use this, only those that measurements show are commonly small. The threshold was at least ~95% of the maps of this kind fitting into the thin schema (that is, have at most 10 elements).

I also switched some `IndexMap`s to `HashMap`s where I believe the order does not matter.
@rustbot

rustbot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants