Skip to content

Commit

Permalink
Auto merge of rust-lang#136159 - urben1680:urben1680-vecdeque-partiti…
Browse files Browse the repository at this point in the history
…on-point-optimization, r=<try>

`VecDeque::partition_point` and `binary_search_by` check first element in `back` slice only once

I noticed that the first element of the back slice is potentially checked twice for the partition_point method, first in an if-condition and second inside the respective body.

EDIT: Applied the same change to `binary_search_by` method.

In this change, the back slice is reduced by the first element and this offset is added to the result.

I am not sure how to trigger benchmarks for this, I assume doing this PR is the way to go for Bors.

Please tell me if this is not how pull requests should be done.
  • Loading branch information
bors committed Jan 31, 2025
2 parents 6c1d960 + a12248c commit 902ee03
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2673,13 +2673,19 @@ impl<T, A: Allocator> VecDeque<T, A> {
where
F: FnMut(&'a T) -> Ordering,
{
let (front, back) = self.as_slices();
let (front, mut back) = self.as_slices();
let cmp_back = back.first().map(|elem| f(elem));

if let Some(Ordering::Equal) = cmp_back {
Ok(front.len())
} else if let Some(Ordering::Less) = cmp_back {
back.binary_search_by(f).map(|idx| idx + front.len()).map_err(|idx| idx + front.len())
back = unsafe {
// SAFETY: if clause has proven a first element to skip exists
back.get_unchecked(1..)
};
back.binary_search_by(f)
.map(|idx| idx + front.len() + 1)
.map_err(|idx| idx + front.len() + 1)
} else {
front.binary_search_by(f)
}
Expand Down Expand Up @@ -2783,10 +2789,14 @@ impl<T, A: Allocator> VecDeque<T, A> {
where
P: FnMut(&T) -> bool,
{
let (front, back) = self.as_slices();
let (front, mut back) = self.as_slices();

if let Some(true) = back.first().map(|v| pred(v)) {
back.partition_point(pred) + front.len()
back = unsafe {
// SAFETY: if clause has proven a first element to skip exists
back.get_unchecked(1..)
};
back.partition_point(pred) + front.len() + 1
} else {
front.partition_point(pred)
}
Expand Down

0 comments on commit 902ee03

Please sign in to comment.