F: FnMut(&T) -> bool,
{
let len = self.len();
- let mut del = 0;
- for i in 0..len {
- if !f(&self[i]) {
- del += 1;
- } else if del > 0 {
- self.swap(i - del, i);
+ let mut idx = 0;
+ let mut cur = 0;
+
+ // Stage 1: All values are retained.
+ while cur < len {
+ if !f(&self[cur]) {
+ cur += 1;
+ break;
}
+ cur += 1;
+ idx += 1;
}
- if del > 0 {
- self.truncate(len - del);
+ // Stage 2: Swap retained value into current idx.
+ while cur < len {
+ if !f(&self[cur]) {
+ cur += 1;
+ continue;
+ }
+
+ self.swap(idx, cur);
+ cur += 1;
+ idx += 1;
+ }
+ // Stage 3: Trancate all values after idx.
+ if cur != idx {
+ self.truncate(idx);
}
}
})
}
+#[bench]
+#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
+fn bench_retain_whole_10000(b: &mut test::Bencher) {
+ let v = (1..100000).collect::<VecDeque<u32>>();
+
+ b.iter(|| {
+ let mut v = v.clone();
+ v.retain(|x| *x > 0)
+ })
+}
+
+#[bench]
+#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
+fn bench_retain_odd_10000(b: &mut test::Bencher) {
+ let v = (1..100000).collect::<VecDeque<u32>>();
+
+ b.iter(|| {
+ let mut v = v.clone();
+ v.retain(|x| x & 1 == 0)
+ })
+}
+
+#[bench]
+#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
+fn bench_retain_half_10000(b: &mut test::Bencher) {
+ let v = (1..100000).collect::<VecDeque<u32>>();
+
+ b.iter(|| {
+ let mut v = v.clone();
+ v.retain(|x| *x > 50000)
+ })
+}
+
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn bench_pop_front_100(b: &mut test::Bencher) {
})
}
+
+
#[test]
fn test_swap_front_back_remove() {
fn test(back: bool) {