Skip to content

perf: Index trait impls by their rigid self type [bitmaps -23%, typenum -18%] - #86

Draft
xmakro wants to merge 1 commit into
perf/base-0713from
perf/trait-impl-rigid-self-index
Draft

perf: Index trait impls by their rigid self type [bitmaps -23%, typenum -18%]#86
xmakro wants to merge 1 commit into
perf/base-0713from
perf/trait-impl-rigid-self-index

Conversation

@xmakro

@xmakro xmakro commented Aug 4, 2026

Copy link
Copy Markdown
Owner

for_each_relevant_impl narrows the impls of a trait down by the outermost layer of the self
type. A trait implemented for many instances of one generic type, impl Bits for BitsImpl<1>
through BitsImpl<1024> say, ends up with all of its impls under one key, so every lookup walks
all of them and runs the deep reject on each. On bitmaps that is 15.7% of the compile in
args_may_unify plus 5.3% in impl_trait_ref.

A self type that contains nothing that could still be inferred or normalized unifies only with a
type equal to it up to regions. Impls with such a self type are therefore relevant to lookups of
that one type only, and can be indexed by it. The impls whose self type is not rigid stay in a
list that every lookup considers, and a lookup of a self type that is not itself rigid falls
back to walking the whole entry. The index is only built for keys with at least 16 impls, and it
is left out of the stable hash because it is derived from the list it refines.

The key is a hash of the region-erased type, which is cheap because types are interned and hash
by address.

Measured on 12 crates, Check and Debug, instructions:u, isolated against the same base:

bitmaps-3.2.1              check   -23.31%
bitmaps-3.2.1              debug   -21.14%
typenum-1.18.0             check   -17.67%
typenum-1.18.0             debug   -17.25%
nalgebra-0.33.0            check    -0.25%
nalgebra-0.33.0            debug    -0.26%

The other 18 cells (cranelift-codegen, clap_derive, hyper, image, many-assoc-items, match-stress,
ripgrep, serde, syn) are all within 0.10%, geomean -3.64%.

The full tests/ui suite passes (21309 tests), as do tests/incremental (178 tests) and the
rustc_pattern_analysis unit tests.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant