forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#75974 - SkiFire13:peekmut-opt-sift, r=Lukas…
…Kalbertodt Avoid useless sift_down when std::collections::binary_heap::PeekMut is never mutably dereferenced If `deref_mut` is never called then it's not possible for the element to be mutated without internal mutability, meaning there's no need to call `sift_down`. This could be a little improvement in cases where you want to mutate the biggest element of the heap only if it satisfies a certain predicate that needs only read access to the element.
- Loading branch information
Showing
3 changed files
with
96 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
use std::collections::BinaryHeap; | ||
|
||
use rand::{seq::SliceRandom, thread_rng}; | ||
use test::{black_box, Bencher}; | ||
|
||
#[bench] | ||
fn bench_find_smallest_1000(b: &mut Bencher) { | ||
let mut rng = thread_rng(); | ||
let mut vec: Vec<u32> = (0..100_000).collect(); | ||
vec.shuffle(&mut rng); | ||
|
||
b.iter(|| { | ||
let mut iter = vec.iter().copied(); | ||
let mut heap: BinaryHeap<_> = iter.by_ref().take(1000).collect(); | ||
|
||
for x in iter { | ||
let mut max = heap.peek_mut().unwrap(); | ||
// This comparison should be true only 1% of the time. | ||
// Unnecessary `sift_down`s will degrade performance | ||
if x < *max { | ||
*max = x; | ||
} | ||
} | ||
|
||
heap | ||
}) | ||
} | ||
|
||
#[bench] | ||
fn bench_peek_mut_deref_mut(b: &mut Bencher) { | ||
let mut bheap = BinaryHeap::from(vec![42]); | ||
let vec: Vec<u32> = (0..1_000_000).collect(); | ||
|
||
b.iter(|| { | ||
let vec = black_box(&vec); | ||
let mut peek_mut = bheap.peek_mut().unwrap(); | ||
// The compiler shouldn't be able to optimize away the `sift_down` | ||
// assignment in `PeekMut`'s `DerefMut` implementation since | ||
// the loop may not run. | ||
for &i in vec.iter() { | ||
*peek_mut = i; | ||
} | ||
// Remove the already minimal overhead of the sift_down | ||
std::mem::forget(peek_mut); | ||
}) | ||
} | ||
|
||
#[bench] | ||
fn bench_from_vec(b: &mut Bencher) { | ||
let mut rng = thread_rng(); | ||
let mut vec: Vec<u32> = (0..100_000).collect(); | ||
vec.shuffle(&mut rng); | ||
|
||
b.iter(|| BinaryHeap::from(vec.clone())) | ||
} | ||
|
||
#[bench] | ||
fn bench_into_sorted_vec(b: &mut Bencher) { | ||
let bheap: BinaryHeap<i32> = (0..10_000).collect(); | ||
|
||
b.iter(|| bheap.clone().into_sorted_vec()) | ||
} | ||
|
||
#[bench] | ||
fn bench_push(b: &mut Bencher) { | ||
let mut bheap = BinaryHeap::with_capacity(50_000); | ||
let mut rng = thread_rng(); | ||
let mut vec: Vec<u32> = (0..50_000).collect(); | ||
vec.shuffle(&mut rng); | ||
|
||
b.iter(|| { | ||
for &i in vec.iter() { | ||
bheap.push(i); | ||
} | ||
black_box(&mut bheap); | ||
bheap.clear(); | ||
}) | ||
} | ||
|
||
#[bench] | ||
fn bench_pop(b: &mut Bencher) { | ||
let mut bheap = BinaryHeap::with_capacity(10_000); | ||
|
||
b.iter(|| { | ||
bheap.extend((0..10_000).rev()); | ||
black_box(&mut bheap); | ||
while let Some(elem) = bheap.pop() { | ||
black_box(elem); | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
|
||
extern crate test; | ||
|
||
mod binary_heap; | ||
mod btree; | ||
mod linked_list; | ||
mod slice; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters