diff --git a/src/hash_map.rs b/src/hash_map.rs index c1cb57d..2b6fbdc 100644 --- a/src/hash_map.rs +++ b/src/hash_map.rs @@ -1,6 +1,6 @@ use std::borrow::Borrow; -use std::collections::{hash_map, HashMap}; use std::collections::hash_map::{IntoKeys, IntoValues}; +use std::collections::{hash_map, HashMap}; use std::fmt::{self, Debug}; use std::hash::{BuildHasher, Hash}; use std::iter::FromIterator; @@ -14,7 +14,6 @@ use serde::{ }; use crate::RandomState; -use crate::random_state::RandomSource; /// A [`HashMap`](std::collections::HashMap) using [`RandomState`](crate::RandomState) to hash the items. /// (Requires the `std` feature to be enabled.) diff --git a/src/hash_set.rs b/src/hash_set.rs index 8d1341a..d03bef5 100644 --- a/src/hash_set.rs +++ b/src/hash_set.rs @@ -1,5 +1,4 @@ use crate::RandomState; -use crate::random_state::RandomSource; use std::collections::{hash_set, HashSet}; use std::fmt::{self, Debug}; use std::hash::{BuildHasher, Hash}; diff --git a/tests/bench.rs b/tests/bench.rs index 84a3739..5bc0fc9 100644 --- a/tests/bench.rs +++ b/tests/bench.rs @@ -3,60 +3,33 @@ use ahash::{AHasher, RandomState}; use criterion::*; use fxhash::FxHasher; +use rand::Rng; use std::collections::hash_map::DefaultHasher; use std::hash::{BuildHasherDefault, Hash, Hasher}; -#[cfg(any( - all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), +// Needs to be in sync with `src/lib.rs` +const AHASH_IMPL: &str = if cfg!(any( all( - any(target_arch = "arm", target_arch = "aarch64"), - any(target_feature = "aes", target_feature = "crypto"), - not(miri), - feature = "stdsimd" - ) -))] -fn aeshash(b: &H) -> u64 { - let build_hasher = RandomState::with_seeds(1, 2, 3, 4); - build_hasher.hash_one(b) -} -#[cfg(not(any( - all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), - all( - any(target_arch = "arm", target_arch = "aarch64"), - any(target_feature = "aes", target_feature = "crypto"), + any(target_arch = "x86", target_arch = "x86_64"), + target_feature = "aes", not(miri), - feature = "stdsimd" - ) -)))] -fn aeshash(_b: &H) -> u64 { - panic!("aes must be enabled") -} - -#[cfg(not(any( - all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), + ), all( any(target_arch = "arm", target_arch = "aarch64"), any(target_feature = "aes", target_feature = "crypto"), not(miri), - feature = "stdsimd" - ) -)))] -fn fallbackhash(b: &H) -> u64 { + feature = "stdsimd", + ), +)) { + "aeshash" +} else { + "fallbackhash" +}; + +fn ahash(b: &H) -> u64 { let build_hasher = RandomState::with_seeds(1, 2, 3, 4); build_hasher.hash_one(b) } -#[cfg(any( - all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), - all( - any(target_arch = "arm", target_arch = "aarch64"), - any(target_feature = "aes", target_feature = "crypto"), - not(miri), - feature = "stdsimd" - ) -))] -fn fallbackhash(_b: &H) -> u64 { - panic!("aes must be disabled") -} fn fnvhash(b: &H) -> u64 { let mut hasher = fnv::FnvHasher::default(); @@ -98,72 +71,44 @@ fn gen_strings() -> Vec { .collect() } -const U8_VALUE: u8 = 123; -const U16_VALUE: u16 = 1234; -const U32_VALUE: u32 = 12345678; -const U64_VALUE: u64 = 1234567890123456; -const U128_VALUE: u128 = 12345678901234567890123456789012; +macro_rules! bench_inputs { + ($group:ident, $hash:ident) => { + // Number of iterations per batch should be high enough to hide timing overhead. + let size = BatchSize::NumIterations(2_000); -#[cfg(target_feature = "aes")] -fn bench_ahash(c: &mut Criterion) { - let mut group = c.benchmark_group("aeshash"); - group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(aeshash(s)))); - group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(aeshash(s)))); - group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(aeshash(s)))); - group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(aeshash(s)))); - group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(aeshash(s)))); - group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(aeshash(s)))); + let mut rng = rand::thread_rng(); + $group.bench_function("u8", |b| b.iter_batched(|| rng.gen::(), |v| $hash(&v), size)); + $group.bench_function("u16", |b| b.iter_batched(|| rng.gen::(), |v| $hash(&v), size)); + $group.bench_function("u32", |b| b.iter_batched(|| rng.gen::(), |v| $hash(&v), size)); + $group.bench_function("u64", |b| b.iter_batched(|| rng.gen::(), |v| $hash(&v), size)); + $group.bench_function("u128", |b| b.iter_batched(|| rng.gen::(), |v| $hash(&v), size)); + $group.bench_with_input("strings", &gen_strings(), |b, s| b.iter(|| $hash(black_box(s)))); + }; } -#[cfg(not(target_feature = "aes"))] -fn bench_fallback(c: &mut Criterion) { - let mut group = c.benchmark_group("fallback"); - group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s)))); - group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s)))); - group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s)))); - group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s)))); - group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s)))); - group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(fallbackhash(s)))); +fn bench_ahash(c: &mut Criterion) { + let mut group = c.benchmark_group(AHASH_IMPL); + bench_inputs!(group, ahash); } fn bench_fx(c: &mut Criterion) { let mut group = c.benchmark_group("fx"); - group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(fxhash(s)))); - group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(fxhash(s)))); - group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(fxhash(s)))); - group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(fxhash(s)))); - group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(fxhash(s)))); - group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(fxhash(s)))); + bench_inputs!(group, fxhash); } fn bench_fnv(c: &mut Criterion) { let mut group = c.benchmark_group("fnv"); - group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(fnvhash(s)))); - group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(fnvhash(s)))); - group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(fnvhash(s)))); - group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(fnvhash(s)))); - group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(fnvhash(s)))); - group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(fnvhash(s)))); + bench_inputs!(group, fnvhash); } fn bench_sea(c: &mut Criterion) { let mut group = c.benchmark_group("sea"); - group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(seahash(s)))); - group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(seahash(s)))); - group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(seahash(s)))); - group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(seahash(s)))); - group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(seahash(s)))); - group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(seahash(s)))); + bench_inputs!(group, seahash); } fn bench_sip(c: &mut Criterion) { let mut group = c.benchmark_group("sip"); - group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(siphash(s)))); - group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(siphash(s)))); - group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(siphash(s)))); - group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(siphash(s)))); - group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(siphash(s)))); - group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(siphash(s)))); + bench_inputs!(group, siphash); } fn bench_map(c: &mut Criterion) { @@ -242,32 +187,12 @@ fn bench_map(c: &mut Criterion) { criterion_main!(benches); -#[cfg(any( - all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), - all( - any(target_arch = "arm", target_arch = "aarch64"), - any(target_feature = "aes", target_feature = "crypto"), - not(miri), - feature = "stdsimd" - ) -))] -criterion_group!(benches, bench_ahash, bench_fx, bench_fnv, bench_sea, bench_sip); - -#[cfg(not(any( - all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), - all( - any(target_arch = "arm", target_arch = "aarch64"), - any(target_feature = "aes", target_feature = "crypto"), - not(miri), - feature = "stdsimd" - ) -)))] criterion_group!( benches, - bench_fallback, + bench_ahash, bench_fx, bench_fnv, bench_sea, bench_sip, - bench_map, + bench_map );