Simplify and optimize SlotIndex::from_index

Break out bucket 0 (containing `idx < 4096`) as an early return, which
simplifies the remainder of the function, and allows optimizing the
`checked_ilog2` since it can no longer return `None`.

This reduces the runtime of `vec_cache::tests::slot_index_exhaustive`
(which calls `SlotIndex::from_index` for every `u32`, twice) from ~15.5s
to ~13.3s.
This commit is contained in:
Josh Triplett
2025-06-05 12:02:04 -07:00
parent df8102fe5f
commit 43ee7cd57c

View File

@@ -68,22 +68,13 @@ impl SlotIndex {
// slots (see `slot_index_exhaustive` in tests).
#[inline]
const fn from_index(idx: u32) -> Self {
let mut bucket = match idx.checked_ilog2() {
Some(x) => x as usize,
None => 0,
};
let entries;
let running_sum;
if bucket <= 11 {
entries = 1 << 12;
running_sum = 0;
bucket = 0;
} else {
entries = 1 << bucket;
running_sum = entries;
bucket = bucket - 11;
if idx < 4096 {
return SlotIndex { bucket_idx: 0, entries: 4096, index_in_bucket: idx as usize };
}
SlotIndex { bucket_idx: bucket, entries, index_in_bucket: idx as usize - running_sum }
// SAFETY: We already ruled out idx 0, so `checked_ilog2` can't return `None`.
let bucket = unsafe { idx.checked_ilog2().unwrap_unchecked() as usize };
let entries = 1 << bucket;
SlotIndex { bucket_idx: bucket - 11, entries, index_in_bucket: idx as usize - entries }
}
// SAFETY: Buckets must be managed solely by functions here (i.e., get/put on SlotIndex) and