2019-02-21 10:26:10 -06:00
|
|
|
use std::collections::BTreeSet;
|
|
|
|
|
2022-05-02 01:10:56 -05:00
|
|
|
use rand::Rng;
|
2019-11-13 17:32:36 -06:00
|
|
|
use test::Bencher;
|
2019-02-21 10:26:10 -06:00
|
|
|
|
2019-03-13 17:01:12 -05:00
|
|
|
fn random(n: usize) -> BTreeSet<usize> {
|
2022-05-02 01:10:56 -05:00
|
|
|
let mut rng = crate::bench_rng();
|
2019-03-13 17:01:12 -05:00
|
|
|
let mut set = BTreeSet::new();
|
|
|
|
while set.len() < n {
|
|
|
|
set.insert(rng.gen());
|
2019-02-21 10:26:10 -06:00
|
|
|
}
|
2019-03-13 17:01:12 -05:00
|
|
|
assert_eq!(set.len(), n);
|
|
|
|
set
|
2019-02-21 10:26:10 -06:00
|
|
|
}
|
|
|
|
|
2019-03-13 17:01:12 -05:00
|
|
|
fn neg(n: usize) -> BTreeSet<i32> {
|
2020-01-12 08:03:37 -06:00
|
|
|
let set: BTreeSet<i32> = (-(n as i32)..=-1).collect();
|
2019-03-13 17:01:12 -05:00
|
|
|
assert_eq!(set.len(), n);
|
|
|
|
set
|
2019-02-21 10:26:10 -06:00
|
|
|
}
|
|
|
|
|
2019-03-13 17:01:12 -05:00
|
|
|
fn pos(n: usize) -> BTreeSet<i32> {
|
2020-01-12 08:03:37 -06:00
|
|
|
let set: BTreeSet<i32> = (1..=(n as i32)).collect();
|
2019-03-13 17:01:12 -05:00
|
|
|
assert_eq!(set.len(), n);
|
|
|
|
set
|
2019-02-21 10:26:10 -06:00
|
|
|
}
|
|
|
|
|
2019-03-13 17:01:12 -05:00
|
|
|
fn stagger(n1: usize, factor: usize) -> [BTreeSet<u32>; 2] {
|
|
|
|
let n2 = n1 * factor;
|
|
|
|
let mut sets = [BTreeSet::new(), BTreeSet::new()];
|
|
|
|
for i in 0..(n1 + n2) {
|
|
|
|
let b = i % (factor + 1) != 0;
|
|
|
|
sets[b as usize].insert(i as u32);
|
2019-02-21 10:26:10 -06:00
|
|
|
}
|
2019-03-13 17:01:12 -05:00
|
|
|
assert_eq!(sets[0].len(), n1);
|
|
|
|
assert_eq!(sets[1].len(), n2);
|
|
|
|
sets
|
2019-02-21 10:26:10 -06:00
|
|
|
}
|
|
|
|
|
2019-03-13 17:01:12 -05:00
|
|
|
macro_rules! set_bench {
|
|
|
|
($name: ident, $set_func: ident, $result_func: ident, $sets: expr) => {
|
2019-02-21 10:26:10 -06:00
|
|
|
#[bench]
|
|
|
|
pub fn $name(b: &mut Bencher) {
|
|
|
|
// setup
|
|
|
|
let sets = $sets;
|
|
|
|
|
|
|
|
// measure
|
2019-11-13 17:32:36 -06:00
|
|
|
b.iter(|| sets[0].$set_func(&sets[1]).$result_func())
|
2019-02-21 10:26:10 -06:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-08-01 06:10:12 -05:00
|
|
|
fn slim_set(n: usize) -> BTreeSet<usize> {
|
|
|
|
(0..n).collect::<BTreeSet<_>>()
|
|
|
|
}
|
|
|
|
|
2020-02-03 05:50:49 -06:00
|
|
|
#[bench]
|
|
|
|
pub fn clone_100(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(100);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| src.clone())
|
|
|
|
}
|
2020-01-12 08:03:37 -06:00
|
|
|
|
|
|
|
#[bench]
|
2020-02-03 05:50:49 -06:00
|
|
|
pub fn clone_100_and_clear(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(100);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| src.clone().clear())
|
2020-01-12 08:03:37 -06:00
|
|
|
}
|
|
|
|
|
2020-02-08 04:52:14 -06:00
|
|
|
#[bench]
|
|
|
|
pub fn clone_100_and_drain_all(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(100);
|
2020-02-08 04:52:14 -06:00
|
|
|
b.iter(|| src.clone().drain_filter(|_| true).count())
|
|
|
|
}
|
|
|
|
|
2020-02-02 05:11:41 -06:00
|
|
|
#[bench]
|
|
|
|
pub fn clone_100_and_drain_half(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(100);
|
2020-02-02 05:11:41 -06:00
|
|
|
b.iter(|| {
|
|
|
|
let mut set = src.clone();
|
2020-02-08 04:52:14 -06:00
|
|
|
assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 100 / 2);
|
2020-02-02 05:11:41 -06:00
|
|
|
assert_eq!(set.len(), 100 / 2);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-01-12 08:03:37 -06:00
|
|
|
#[bench]
|
2020-02-03 05:50:49 -06:00
|
|
|
pub fn clone_100_and_into_iter(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(100);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| src.clone().into_iter().count())
|
2020-01-12 08:03:37 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2020-02-03 05:50:49 -06:00
|
|
|
pub fn clone_100_and_pop_all(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(100);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| {
|
|
|
|
let mut set = src.clone();
|
|
|
|
while set.pop_first().is_some() {}
|
|
|
|
set
|
|
|
|
});
|
2020-01-12 08:03:37 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2020-02-03 05:50:49 -06:00
|
|
|
pub fn clone_100_and_remove_all(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(100);
|
2020-01-12 08:03:37 -06:00
|
|
|
b.iter(|| {
|
2020-02-03 05:50:49 -06:00
|
|
|
let mut set = src.clone();
|
|
|
|
while let Some(elt) = set.iter().copied().next() {
|
2020-08-01 06:10:12 -05:00
|
|
|
let ok = set.remove(&elt);
|
|
|
|
debug_assert!(ok);
|
2020-02-03 05:50:49 -06:00
|
|
|
}
|
|
|
|
set
|
2020-01-12 08:03:37 -06:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2020-02-03 05:50:49 -06:00
|
|
|
pub fn clone_100_and_remove_half(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(100);
|
2020-01-12 08:03:37 -06:00
|
|
|
b.iter(|| {
|
2020-02-03 05:50:49 -06:00
|
|
|
let mut set = src.clone();
|
2020-08-01 06:10:12 -05:00
|
|
|
for i in (0..100).step_by(2) {
|
|
|
|
let ok = set.remove(&i);
|
|
|
|
debug_assert!(ok);
|
2020-01-12 08:03:37 -06:00
|
|
|
}
|
2020-02-03 05:50:49 -06:00
|
|
|
assert_eq!(set.len(), 100 / 2);
|
|
|
|
set
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
pub fn clone_10k(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(10_000);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| src.clone())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
pub fn clone_10k_and_clear(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(10_000);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| src.clone().clear())
|
|
|
|
}
|
|
|
|
|
2020-02-08 04:52:14 -06:00
|
|
|
#[bench]
|
|
|
|
pub fn clone_10k_and_drain_all(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(10_000);
|
2020-02-08 04:52:14 -06:00
|
|
|
b.iter(|| src.clone().drain_filter(|_| true).count())
|
|
|
|
}
|
|
|
|
|
2020-02-02 05:11:41 -06:00
|
|
|
#[bench]
|
|
|
|
pub fn clone_10k_and_drain_half(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(10_000);
|
2020-02-02 05:11:41 -06:00
|
|
|
b.iter(|| {
|
|
|
|
let mut set = src.clone();
|
2020-02-08 04:52:14 -06:00
|
|
|
assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 10_000 / 2);
|
2020-02-02 05:11:41 -06:00
|
|
|
assert_eq!(set.len(), 10_000 / 2);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-02-03 05:50:49 -06:00
|
|
|
#[bench]
|
|
|
|
pub fn clone_10k_and_into_iter(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(10_000);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| src.clone().into_iter().count())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
pub fn clone_10k_and_pop_all(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(10_000);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| {
|
|
|
|
let mut set = src.clone();
|
|
|
|
while set.pop_first().is_some() {}
|
|
|
|
set
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
pub fn clone_10k_and_remove_all(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(10_000);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| {
|
|
|
|
let mut set = src.clone();
|
|
|
|
while let Some(elt) = set.iter().copied().next() {
|
2020-08-01 06:10:12 -05:00
|
|
|
let ok = set.remove(&elt);
|
|
|
|
debug_assert!(ok);
|
2020-02-03 05:50:49 -06:00
|
|
|
}
|
|
|
|
set
|
2020-01-12 08:03:37 -06:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-02-03 05:50:49 -06:00
|
|
|
#[bench]
|
|
|
|
pub fn clone_10k_and_remove_half(b: &mut Bencher) {
|
2020-08-01 06:10:12 -05:00
|
|
|
let src = slim_set(10_000);
|
2020-02-03 05:50:49 -06:00
|
|
|
b.iter(|| {
|
|
|
|
let mut set = src.clone();
|
2020-08-01 06:10:12 -05:00
|
|
|
for i in (0..10_000).step_by(2) {
|
|
|
|
let ok = set.remove(&i);
|
|
|
|
debug_assert!(ok);
|
2020-02-03 05:50:49 -06:00
|
|
|
}
|
|
|
|
assert_eq!(set.len(), 10_000 / 2);
|
|
|
|
set
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-03-13 17:01:12 -05:00
|
|
|
set_bench! {intersection_100_neg_vs_100_pos, intersection, count, [neg(100), pos(100)]}
|
|
|
|
set_bench! {intersection_100_neg_vs_10k_pos, intersection, count, [neg(100), pos(10_000)]}
|
|
|
|
set_bench! {intersection_100_pos_vs_100_neg, intersection, count, [pos(100), neg(100)]}
|
|
|
|
set_bench! {intersection_100_pos_vs_10k_neg, intersection, count, [pos(100), neg(10_000)]}
|
|
|
|
set_bench! {intersection_10k_neg_vs_100_pos, intersection, count, [neg(10_000), pos(100)]}
|
|
|
|
set_bench! {intersection_10k_neg_vs_10k_pos, intersection, count, [neg(10_000), pos(10_000)]}
|
|
|
|
set_bench! {intersection_10k_pos_vs_100_neg, intersection, count, [pos(10_000), neg(100)]}
|
|
|
|
set_bench! {intersection_10k_pos_vs_10k_neg, intersection, count, [pos(10_000), neg(10_000)]}
|
|
|
|
set_bench! {intersection_random_100_vs_100, intersection, count, [random(100), random(100)]}
|
|
|
|
set_bench! {intersection_random_100_vs_10k, intersection, count, [random(100), random(10_000)]}
|
|
|
|
set_bench! {intersection_random_10k_vs_100, intersection, count, [random(10_000), random(100)]}
|
|
|
|
set_bench! {intersection_random_10k_vs_10k, intersection, count, [random(10_000), random(10_000)]}
|
|
|
|
set_bench! {intersection_staggered_100_vs_100, intersection, count, stagger(100, 1)}
|
|
|
|
set_bench! {intersection_staggered_10k_vs_10k, intersection, count, stagger(10_000, 1)}
|
|
|
|
set_bench! {intersection_staggered_100_vs_10k, intersection, count, stagger(100, 100)}
|
|
|
|
set_bench! {difference_random_100_vs_100, difference, count, [random(100), random(100)]}
|
|
|
|
set_bench! {difference_random_100_vs_10k, difference, count, [random(100), random(10_000)]}
|
|
|
|
set_bench! {difference_random_10k_vs_100, difference, count, [random(10_000), random(100)]}
|
|
|
|
set_bench! {difference_random_10k_vs_10k, difference, count, [random(10_000), random(10_000)]}
|
|
|
|
set_bench! {difference_staggered_100_vs_100, difference, count, stagger(100, 1)}
|
|
|
|
set_bench! {difference_staggered_10k_vs_10k, difference, count, stagger(10_000, 1)}
|
|
|
|
set_bench! {difference_staggered_100_vs_10k, difference, count, stagger(100, 100)}
|
|
|
|
set_bench! {is_subset_100_vs_100, is_subset, clone, [pos(100), pos(100)]}
|
|
|
|
set_bench! {is_subset_100_vs_10k, is_subset, clone, [pos(100), pos(10_000)]}
|
|
|
|
set_bench! {is_subset_10k_vs_100, is_subset, clone, [pos(10_000), pos(100)]}
|
|
|
|
set_bench! {is_subset_10k_vs_10k, is_subset, clone, [pos(10_000), pos(10_000)]}
|