use fnv::FnvHasher; use std::hash::BuildHasherDefault; use std::hash::Hash; type FnvBuilder = BuildHasherDefault<FnvHasher>;
use test::black_box; use test::Bencher;
use indexmap::IndexMap;
use std::collections::HashMap;
use rand::rngs::SmallRng; use rand::seq::SliceRandom; use rand::SeedableRng;
/// Use a consistently seeded Rng for benchmark stability fn small_rng() -> SmallRng { let seed = u64::from_le_bytes(*b"indexmap");
SmallRng::seed_from_u64(seed)
}
#[bench] fn insert_hashmap_10_000(b: &mut Bencher) { let c = 10_000;
b.iter(|| { letmut map = HashMap::with_capacity(c); for x in0..c {
map.insert(x, ());
}
map
});
}
#[bench] fn insert_indexmap_10_000(b: &mut Bencher) { let c = 10_000;
b.iter(|| { letmut map = IndexMap::with_capacity(c); for x in0..c {
map.insert(x, ());
}
map
});
}
#[bench] fn insert_hashmap_string_10_000(b: &mut Bencher) { let c = 10_000;
b.iter(|| { letmut map = HashMap::with_capacity(c); for x in0..c {
map.insert(x.to_string(), ());
}
map
});
}
#[bench] fn insert_indexmap_string_10_000(b: &mut Bencher) { let c = 10_000;
b.iter(|| { letmut map = IndexMap::with_capacity(c); for x in0..c {
map.insert(x.to_string(), ());
}
map
});
}
#[bench] fn insert_hashmap_str_10_000(b: &mut Bencher) { let c = 10_000; let ss = Vec::from_iter((0..c).map(|x| x.to_string()));
b.iter(|| { letmut map = HashMap::with_capacity(c); for key in &ss {
map.insert(&key[..], ());
}
map
});
}
#[bench] fn insert_indexmap_str_10_000(b: &mut Bencher) { let c = 10_000; let ss = Vec::from_iter((0..c).map(|x| x.to_string()));
b.iter(|| { letmut map = IndexMap::with_capacity(c); for key in &ss {
map.insert(&key[..], ());
}
map
});
}
#[bench] fn insert_hashmap_int_bigvalue_10_000(b: &mut Bencher) { let c = 10_000; let value = [0u64; 10];
b.iter(|| { letmut map = HashMap::with_capacity(c); for i in0..c {
map.insert(i, value);
}
map
});
}
#[bench] fn insert_indexmap_int_bigvalue_10_000(b: &mut Bencher) { let c = 10_000; let value = [0u64; 10];
b.iter(|| { letmut map = IndexMap::with_capacity(c); for i in0..c {
map.insert(i, value);
}
map
});
}
#[bench] fn insert_hashmap_100_000(b: &mut Bencher) { let c = 100_000;
b.iter(|| { letmut map = HashMap::with_capacity(c); for x in0..c {
map.insert(x, ());
}
map
});
}
#[bench] fn insert_indexmap_100_000(b: &mut Bencher) { let c = 100_000;
b.iter(|| { letmut map = IndexMap::with_capacity(c); for x in0..c {
map.insert(x, ());
}
map
});
}
#[bench] fn insert_hashmap_150(b: &mut Bencher) { let c = 150;
b.iter(|| { letmut map = HashMap::with_capacity(c); for x in0..c {
map.insert(x, ());
}
map
});
}
#[bench] fn insert_indexmap_150(b: &mut Bencher) { let c = 150;
b.iter(|| { letmut map = IndexMap::with_capacity(c); for x in0..c {
map.insert(x, ());
}
map
});
}
#[bench] fn entry_hashmap_150(b: &mut Bencher) { let c = 150;
b.iter(|| { letmut map = HashMap::with_capacity(c); for x in0..c {
map.entry(x).or_insert(());
}
map
});
}
#[bench] fn entry_indexmap_150(b: &mut Bencher) { let c = 150;
b.iter(|| { letmut map = IndexMap::with_capacity(c); for x in0..c {
map.entry(x).or_insert(());
}
map
});
}
#[bench] fn iter_sum_hashmap_10_000(b: &mut Bencher) { let c = 10_000; letmut map = HashMap::with_capacity(c); let len = c - c / 10; for x in0..len {
map.insert(x, ());
}
assert_eq!(map.len(), len);
b.iter(|| map.keys().sum::<usize>());
}
#[bench] fn iter_sum_indexmap_10_000(b: &mut Bencher) { let c = 10_000; letmut map = IndexMap::with_capacity(c); let len = c - c / 10; for x in0..len {
map.insert(x, ());
}
assert_eq!(map.len(), len);
b.iter(|| map.keys().sum::<usize>());
}
#[bench] fn iter_black_box_hashmap_10_000(b: &mut Bencher) { let c = 10_000; letmut map = HashMap::with_capacity(c); let len = c - c / 10; for x in0..len {
map.insert(x, ());
}
assert_eq!(map.len(), len);
b.iter(|| { for &key in map.keys() {
black_box(key);
}
});
}
#[bench] fn iter_black_box_indexmap_10_000(b: &mut Bencher) { let c = 10_000; letmut map = IndexMap::with_capacity(c); let len = c - c / 10; for x in0..len {
map.insert(x, ());
}
assert_eq!(map.len(), len);
b.iter(|| { for &key in map.keys() {
black_box(key);
}
});
}
fn shuffled_keys<I>(iter: I) -> Vec<I::Item> where
I: IntoIterator,
{ letmut v = Vec::from_iter(iter); letmut rng = small_rng();
v.shuffle(&mut rng);
v
}
#[bench] fn lookup_hashmap_10_000_exist(b: &mut Bencher) { let c = 10_000; letmut map = HashMap::with_capacity(c); let keys = shuffled_keys(0..c); for &key in &keys {
map.insert(key, 1);
}
b.iter(|| { letmut found = 0; for key in5000..c {
found += map.get(&key).is_some() as i32;
}
found
});
}
#[bench] fn lookup_hashmap_10_000_noexist(b: &mut Bencher) { let c = 10_000; letmut map = HashMap::with_capacity(c); let keys = shuffled_keys(0..c); for &key in &keys {
map.insert(key, 1);
}
b.iter(|| { letmut found = 0; for key in c..15000 {
found += map.get(&key).is_some() as i32;
}
found
});
}
#[bench] fn lookup_indexmap_10_000_exist(b: &mut Bencher) { let c = 10_000; letmut map = IndexMap::with_capacity(c); let keys = shuffled_keys(0..c); for &key in &keys {
map.insert(key, 1);
}
b.iter(|| { letmut found = 0; for key in5000..c {
found += map.get(&key).is_some() as i32;
}
found
});
}
#[bench] fn lookup_indexmap_10_000_noexist(b: &mut Bencher) { let c = 10_000; letmut map = IndexMap::with_capacity(c); let keys = shuffled_keys(0..c); for &key in &keys {
map.insert(key, 1);
}
b.iter(|| { letmut found = 0; for key in c..15000 {
found += map.get(&key).is_some() as i32;
}
found
});
}
// number of items to look up const LOOKUP_MAP_SIZE: u32 = 100_000_u32; const LOOKUP_SAMPLE_SIZE: u32 = 5000; const SORT_MAP_SIZE: usize = 10_000;
// use lazy_static so that comparison benchmarks use the exact same inputs
lazy_static! { staticref KEYS: Vec<u32> = shuffled_keys(0..LOOKUP_MAP_SIZE);
}
lazy_static! { staticref HMAP_100K: HashMap<u32, u32> = { let c = LOOKUP_MAP_SIZE; letmut map = HashMap::with_capacity(c as usize); let keys = &*KEYS; for &key in keys {
map.insert(key, key);
}
map
};
}
lazy_static! { staticref IMAP_100K: IndexMap<u32, u32> = { let c = LOOKUP_MAP_SIZE; letmut map = IndexMap::with_capacity(c as usize); let keys = &*KEYS; for &key in keys {
map.insert(key, key);
}
map
};
}
#[bench] fn lookup_hashmap_100_000_multi(b: &mut Bencher) { let map = &*HMAP_100K;
b.iter(|| { letmut found = 0; for key in0..LOOKUP_SAMPLE_SIZE {
found += map.get(&key).is_some() as u32;
}
found
});
}
#[bench] fn lookup_indexmap_100_000_multi(b: &mut Bencher) { let map = &*IMAP_100K;
b.iter(|| { letmut found = 0; for key in0..LOOKUP_SAMPLE_SIZE {
found += map.get(&key).is_some() as u32;
}
found
});
}
// inorder: Test looking up keys in the same order as they were inserted #[bench] fn lookup_hashmap_100_000_inorder_multi(b: &mut Bencher) { let map = &*HMAP_100K; let keys = &*KEYS;
b.iter(|| { letmut found = 0; for key in &keys[0..LOOKUP_SAMPLE_SIZE as usize] {
found += map.get(key).is_some() as u32;
}
found
});
}
#[bench] fn lookup_indexmap_100_000_inorder_multi(b: &mut Bencher) { let map = &*IMAP_100K; let keys = &*KEYS;
b.iter(|| { letmut found = 0; for key in &keys[0..LOOKUP_SAMPLE_SIZE as usize] {
found += map.get(key).is_some() as u32;
}
found
});
}
#[bench] fn lookup_hashmap_100_000_single(b: &mut Bencher) { let map = &*HMAP_100K; letmut iter = (0..LOOKUP_MAP_SIZE + LOOKUP_SAMPLE_SIZE).cycle();
b.iter(|| { let key = iter.next().unwrap();
map.get(&key).is_some()
});
}
#[bench] fn lookup_indexmap_100_000_single(b: &mut Bencher) { let map = &*IMAP_100K; letmut iter = (0..LOOKUP_MAP_SIZE + LOOKUP_SAMPLE_SIZE).cycle();
b.iter(|| { let key = iter.next().unwrap();
map.get(&key).is_some()
});
}
const GROW_SIZE: usize = 100_000; type GrowKey = u32;
// Test grow/resize without preallocation #[bench] fn grow_fnv_hashmap_100_000(b: &mut Bencher) {
b.iter(|| { letmut map: HashMap<_, _, FnvBuilder> = HashMap::default(); for x in0..GROW_SIZE {
map.insert(x as GrowKey, x as GrowKey);
}
map
});
}
#[bench] fn grow_fnv_indexmap_100_000(b: &mut Bencher) {
b.iter(|| { letmut map: IndexMap<_, _, FnvBuilder> = IndexMap::default(); for x in0..GROW_SIZE {
map.insert(x as GrowKey, x as GrowKey);
}
map
});
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.