Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 25f8d01

Browse files
committed
Auto merge of #114231 - ttsugriy:binary_search_slice, r=cjgillot
[rustc_data_structures] Use partition_point to find slice range end. This PR uses approach introduced in #114152 to find the end of the range. It's much easier to understand and reason about invariants of such implementation. Technically it's possible to make it even shorter by returning `&[start..end]` unconditionally because even if searched item is not present in the slice, `start` and `end` would point at the same index, so the range would be empty. The reason I decided not to use this shorter implementation is because it would involve more comparisons in case there are no elements in the slice with key equal to `key`. Also, not that it matters much, but this implementation also improves perf according to the benchmark below: https://gist.github.com/ttsugriy/63c0ed39ae132b131931fa1f8a3dea55 The results on my M1 macbook air are: ``` Running benches/bin_search_slice_benchmark.rs (target/release/deps/bin_search_slice_benchmark-90fa6d68c3bd1298) Benchmarking multiply add/binary_search_slice: Collecting 100 samples in estimated 5.0002 s (1 multiply add/binary_search_slice time: [44.719 ns 44.918 ns 45.158 ns] No change in performance detected. Found 3 outliers among 100 measurements (3.00%) 1 (1.00%) high mild 2 (2.00%) high severe Benchmarking multiply add/binary_search_slice_new: Collecting 100 samples in estimated 5.0001 multiply add/binary_search_slice_new time: [36.955 ns 37.060 ns 37.221 ns] No change in performance detected. Found 7 outliers among 100 measurements (7.00%) 3 (3.00%) high mild 4 (4.00%) high severe ```
2 parents 8424f8e + 97bc528 commit 25f8d01

File tree

1 file changed

+4
-21
lines changed
  • compiler/rustc_data_structures/src/binary_search_util

1 file changed

+4
-21
lines changed

‎compiler/rustc_data_structures/src/binary_search_util/mod.rs

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,10 @@ where
1818
return &[];
1919
};
2020

21-
// Now search forward to find the *last* one.
22-
let mut end = start;
23-
let mut previous = start;
24-
let mut step = 1;
25-
loop {
26-
end = end.saturating_add(step).min(size);
27-
if end == size || key_fn(&data[end]) != *key {
28-
break;
29-
}
30-
previous = end;
31-
step *= 2;
32-
}
33-
step = end - previous;
34-
while step > 1 {
35-
let half = step / 2;
36-
let mid = end - half;
37-
if key_fn(&data[mid]) != *key {
38-
end = mid;
39-
}
40-
step -= half;
41-
}
21+
// Find the first entry with key > `key`. Skip `start` entries since
22+
// key_fn(&data[start]) == *key
23+
let offset = start + 1;
24+
let end = data[offset..].partition_point(|x| key_fn(x) <= *key) + offset;
4225

4326
&data[start..end]
4427
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /