Skip to content

Commit 902ee03

Browse files
committedJan 31, 2025
Auto merge of #136159 - urben1680:urben1680-vecdeque-partition-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.
2 parents 6c1d960 + a12248c commit 902ee03

File tree

1 file changed

+14
-4
lines changed
  • library/alloc/src/collections/vec_deque

1 file changed

+14
-4
lines changed
 

‎library/alloc/src/collections/vec_deque/mod.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -2673,13 +2673,19 @@ impl<T, A: Allocator> VecDeque<T, A> {
26732673
where
26742674
F: FnMut(&'a T) -> Ordering,
26752675
{
2676-
let (front, back) = self.as_slices();
2676+
let (front, mut back) = self.as_slices();
26772677
let cmp_back = back.first().map(|elem| f(elem));
26782678

26792679
if let Some(Ordering::Equal) = cmp_back {
26802680
Ok(front.len())
26812681
} else if let Some(Ordering::Less) = cmp_back {
2682-
back.binary_search_by(f).map(|idx| idx + front.len()).map_err(|idx| idx + front.len())
2682+
back = unsafe {
2683+
// SAFETY: if clause has proven a first element to skip exists
2684+
back.get_unchecked(1..)
2685+
};
2686+
back.binary_search_by(f)
2687+
.map(|idx| idx + front.len() + 1)
2688+
.map_err(|idx| idx + front.len() + 1)
26832689
} else {
26842690
front.binary_search_by(f)
26852691
}
@@ -2783,10 +2789,14 @@ impl<T, A: Allocator> VecDeque<T, A> {
27832789
where
27842790
P: FnMut(&T) -> bool,
27852791
{
2786-
let (front, back) = self.as_slices();
2792+
let (front, mut back) = self.as_slices();
27872793

27882794
if let Some(true) = back.first().map(|v| pred(v)) {
2789-
back.partition_point(pred) + front.len()
2795+
back = unsafe {
2796+
// SAFETY: if clause has proven a first element to skip exists
2797+
back.get_unchecked(1..)
2798+
};
2799+
back.partition_point(pred) + front.len() + 1
27902800
} else {
27912801
front.partition_point(pred)
27922802
}

0 commit comments

Comments
 (0)