aboutsummaryrefslogtreecommitdiff
path: root/benches/bench.rs
diff options
context:
space:
mode:
Diffstat (limited to 'benches/bench.rs')
-rw-r--r--benches/bench.rs101
1 files changed, 86 insertions, 15 deletions
diff --git a/benches/bench.rs b/benches/bench.rs
index 771e716..568c513 100644
--- a/benches/bench.rs
+++ b/benches/bench.rs
@@ -9,8 +9,11 @@ extern crate test;
use test::{black_box, Bencher};
use hashbrown::hash_map::DefaultHashBuilder;
-use hashbrown::HashMap;
-use std::collections::hash_map::RandomState;
+use hashbrown::{HashMap, HashSet};
+use std::{
+ collections::hash_map::RandomState,
+ sync::atomic::{self, AtomicUsize},
+};
const SIZE: usize = 1000;
@@ -40,6 +43,20 @@ impl Iterator for RandomKeys {
}
}
+// Just an arbitrary side effect to make the maps not shortcircuit to the non-dropping path
+// when dropping maps/entries (most real world usages likely have drop in the key or value)
+lazy_static::lazy_static! {
+ static ref SIDE_EFFECT: AtomicUsize = AtomicUsize::new(0);
+}
+
+#[derive(Clone)]
+struct DropType(usize);
+impl Drop for DropType {
+ fn drop(&mut self) {
+ SIDE_EFFECT.fetch_add(self.0, atomic::Ordering::SeqCst);
+ }
+}
+
macro_rules! bench_suite {
($bench_macro:ident, $bench_ahash_serial:ident, $bench_std_serial:ident,
$bench_ahash_highbits:ident, $bench_std_highbits:ident,
@@ -69,10 +86,11 @@ macro_rules! bench_insert {
b.iter(|| {
m.clear();
for i in ($keydist).take(SIZE) {
- m.insert(i, i);
+ m.insert(i, (DropType(i), [i; 20]));
}
black_box(&mut m);
- })
+ });
+ eprintln!("{}", SIDE_EFFECT.load(atomic::Ordering::SeqCst));
}
};
}
@@ -87,13 +105,38 @@ bench_suite!(
insert_std_random
);
+macro_rules! bench_grow_insert {
+ ($name:ident, $maptype:ident, $keydist:expr) => {
+ #[bench]
+ fn $name(b: &mut Bencher) {
+ b.iter(|| {
+ let mut m = $maptype::default();
+ for i in ($keydist).take(SIZE) {
+ m.insert(i, DropType(i));
+ }
+ black_box(&mut m);
+ })
+ }
+ };
+}
+
+bench_suite!(
+ bench_grow_insert,
+ grow_insert_ahash_serial,
+ grow_insert_std_serial,
+ grow_insert_ahash_highbits,
+ grow_insert_std_highbits,
+ grow_insert_ahash_random,
+ grow_insert_std_random
+);
+
macro_rules! bench_insert_erase {
($name:ident, $maptype:ident, $keydist:expr) => {
#[bench]
fn $name(b: &mut Bencher) {
let mut base = $maptype::default();
for i in ($keydist).take(SIZE) {
- base.insert(i, i);
+ base.insert(i, DropType(i));
}
let skip = $keydist.skip(SIZE);
b.iter(|| {
@@ -103,11 +146,12 @@ macro_rules! bench_insert_erase {
// While keeping the size constant,
// replace the first keydist with the second.
for (add, remove) in (&mut add_iter).zip(&mut remove_iter).take(SIZE) {
- m.insert(add, add);
+ m.insert(add, DropType(add));
black_box(m.remove(&remove));
}
black_box(m);
- })
+ });
+ eprintln!("{}", SIDE_EFFECT.load(atomic::Ordering::SeqCst));
}
};
}
@@ -128,14 +172,15 @@ macro_rules! bench_lookup {
fn $name(b: &mut Bencher) {
let mut m = $maptype::default();
for i in $keydist.take(SIZE) {
- m.insert(i, i);
+ m.insert(i, DropType(i));
}
b.iter(|| {
for i in $keydist.take(SIZE) {
black_box(m.get(&i));
}
- })
+ });
+ eprintln!("{}", SIDE_EFFECT.load(atomic::Ordering::SeqCst));
}
};
}
@@ -157,7 +202,7 @@ macro_rules! bench_lookup_fail {
let mut m = $maptype::default();
let mut iter = $keydist;
for i in (&mut iter).take(SIZE) {
- m.insert(i, i);
+ m.insert(i, DropType(i));
}
b.iter(|| {
@@ -185,7 +230,7 @@ macro_rules! bench_iter {
fn $name(b: &mut Bencher) {
let mut m = $maptype::default();
for i in ($keydist).take(SIZE) {
- m.insert(i, i);
+ m.insert(i, DropType(i));
}
b.iter(|| {
@@ -211,7 +256,7 @@ bench_suite!(
fn clone_small(b: &mut Bencher) {
let mut m = HashMap::new();
for i in 0..10 {
- m.insert(i, i);
+ m.insert(i, DropType(i));
}
b.iter(|| {
@@ -224,7 +269,7 @@ fn clone_from_small(b: &mut Bencher) {
let mut m = HashMap::new();
let mut m2 = HashMap::new();
for i in 0..10 {
- m.insert(i, i);
+ m.insert(i, DropType(i));
}
b.iter(|| {
@@ -237,7 +282,7 @@ fn clone_from_small(b: &mut Bencher) {
fn clone_large(b: &mut Bencher) {
let mut m = HashMap::new();
for i in 0..1000 {
- m.insert(i, i);
+ m.insert(i, DropType(i));
}
b.iter(|| {
@@ -250,7 +295,7 @@ fn clone_from_large(b: &mut Bencher) {
let mut m = HashMap::new();
let mut m2 = HashMap::new();
for i in 0..1000 {
- m.insert(i, i);
+ m.insert(i, DropType(i));
}
b.iter(|| {
@@ -258,3 +303,29 @@ fn clone_from_large(b: &mut Bencher) {
black_box(&mut m2);
})
}
+
+#[bench]
+fn rehash_in_place(b: &mut Bencher) {
+ b.iter(|| {
+ let mut set = HashSet::new();
+
+ // Each loop triggers one rehash
+ for _ in 0..10 {
+ for i in 0..224 {
+ set.insert(i);
+ }
+
+ assert_eq!(
+ set.capacity(),
+ 224,
+ "The set must be at or close to capacity to trigger a re hashing"
+ );
+
+ for i in 100..1400 {
+ set.remove(&(i - 100));
+ set.insert(i);
+ }
+ set.clear();
+ }
+ });
+}