Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Changed the default hasher to rapidhash. (#563)

## [0.15.5](https://github.com/rust-lang/hashbrown/compare/v0.15.4...v0.15.5) - 2025-08-07

### Added
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ rust-version = "1.65.0"

[dependencies]
# For the default hasher
foldhash = { version = "0.1.2", default-features = false, optional = true }
rapidhash = { version = "4.0.0", default-features = false, optional = true }

# For external trait impls
rayon = { version = "1.2", optional = true }
Expand Down Expand Up @@ -62,10 +62,10 @@ rustc-dep-of-std = [
# Enables the deprecated RawEntry API.
raw-entry = []

# Provides a default hasher. Currently this is foldhash but this is subject to
# Provides a default hasher. Currently this is rapidhash but this is subject to
# change in the future. Note that the default hasher does *not* provide HashDoS
# resistance, unlike the one in the standard library.
default-hasher = ["dep:foldhash"]
default-hasher = ["dep:rapidhash"]

# Enables usage of `#[inline]` on far more functions than by default in this
# crate. This may lead to a performance increase but often comes at a compile
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ in environments without `std`, such as embedded systems and kernels.
## Features

- Drop-in replacement for the standard library `HashMap` and `HashSet` types.
- Uses [foldhash](https://github.com/orlp/foldhash) as the default hasher, which is much faster than SipHash.
However, foldhash does *not provide the same level of HashDoS resistance* as SipHash, so if that is important to you, you might want to consider using a different hasher.
- Uses [rapidhash](https://github.com/hoxxep/rapidhash) as the default hasher, which is much faster than SipHash.
However, rapidhash does *not provide the same level of HashDoS resistance* as SipHash, so if that is important to you, you might want to consider using a different hasher.
- Around 2x faster than the previous standard library `HashMap`.
- Lower memory usage: only 1 byte of overhead per entry instead of 8.
- Compatible with `#[no_std]` (but requires a global allocator with the `alloc` crate).
Expand Down Expand Up @@ -61,7 +61,7 @@ This crate has the following Cargo features:
- `raw-entry`: Enables access to the deprecated `RawEntry` API.
- `inline-more`: Adds inline hints to most functions, improving run-time performance at the cost
of compilation time. (enabled by default)
- `default-hasher`: Compiles with foldhash as default hasher. (enabled by default)
- `default-hasher`: Compiles with rapidhash as default hasher. (enabled by default)
- `allocator-api2`: Enables support for allocators that support `allocator-api2`. (enabled by default)

## License
Expand Down
70 changes: 35 additions & 35 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This benchmark suite contains some benchmarks along a set of dimensions:
// Hasher: std default (SipHash) and crate default (foldhash).
// Hasher: std default (SipHash) and crate default (rapidhash).
// Int key distribution: low bit heavy, top bit heavy, and random.
// Task: basic functionality: insert, insert_erase, lookup, lookup_fail, iter
#![feature(test)]
Expand All @@ -19,7 +19,7 @@ const SIZE: usize = 1000;
const OP_COUNT: usize = 500;

// The default hashmap when using this crate directly.
type FoldHashMap<K, V> = HashMap<K, V, DefaultHashBuilder>;
type RapidHashMap<K, V> = HashMap<K, V, DefaultHashBuilder>;
// This uses the hashmap from this crate with the default hasher of the stdlib.
type StdHashMap<K, V> = HashMap<K, V, RandomState>;

Expand Down Expand Up @@ -57,22 +57,22 @@ impl Drop for DropType {
}

macro_rules! bench_suite {
($bench_macro:ident, $bench_foldhash_serial:ident, $bench_std_serial:ident,
$bench_foldhash_highbits:ident, $bench_std_highbits:ident,
$bench_foldhash_random:ident, $bench_std_random:ident) => {
$bench_macro!($bench_foldhash_serial, FoldHashMap, 0..);
($bench_macro:ident, $bench_rapidhash_serial:ident, $bench_std_serial:ident,
$bench_rapidhash_highbits:ident, $bench_std_highbits:ident,
$bench_rapidhash_random:ident, $bench_std_random:ident) => {
$bench_macro!($bench_rapidhash_serial, RapidHashMap, 0..);
$bench_macro!($bench_std_serial, StdHashMap, 0..);
$bench_macro!(
$bench_foldhash_highbits,
FoldHashMap,
$bench_rapidhash_highbits,
RapidHashMap,
(0..).map(usize::swap_bytes)
);
$bench_macro!(
$bench_std_highbits,
StdHashMap,
(0..).map(usize::swap_bytes)
);
$bench_macro!($bench_foldhash_random, FoldHashMap, RandomKeys::new());
$bench_macro!($bench_rapidhash_random, RapidHashMap, RandomKeys::new());
$bench_macro!($bench_std_random, StdHashMap, RandomKeys::new());
};
}
Expand All @@ -82,14 +82,14 @@ macro_rules! bench_suite_2 {
$name0:ident, $size0:literal, $name1:ident, $size1:literal, $name2:ident, $size2:literal,
$name3:ident, $size3:literal, $name4:ident, $size4:literal, $name5:ident, $size5:literal,
$name6:ident, $size6:literal, $name7:ident, $size7:literal) => {
$bench_macro!($name0, $size0, FoldHashMap, RandomKeys::new());
$bench_macro!($name1, $size1, FoldHashMap, RandomKeys::new());
$bench_macro!($name2, $size2, FoldHashMap, RandomKeys::new());
$bench_macro!($name3, $size3, FoldHashMap, RandomKeys::new());
$bench_macro!($name4, $size4, FoldHashMap, RandomKeys::new());
$bench_macro!($name5, $size5, FoldHashMap, RandomKeys::new());
$bench_macro!($name6, $size6, FoldHashMap, RandomKeys::new());
$bench_macro!($name7, $size7, FoldHashMap, RandomKeys::new());
$bench_macro!($name0, $size0, RapidHashMap, RandomKeys::new());
$bench_macro!($name1, $size1, RapidHashMap, RandomKeys::new());
$bench_macro!($name2, $size2, RapidHashMap, RandomKeys::new());
$bench_macro!($name3, $size3, RapidHashMap, RandomKeys::new());
$bench_macro!($name4, $size4, RapidHashMap, RandomKeys::new());
$bench_macro!($name5, $size5, RapidHashMap, RandomKeys::new());
$bench_macro!($name6, $size6, RapidHashMap, RandomKeys::new());
$bench_macro!($name7, $size7, RapidHashMap, RandomKeys::new());
};
}

Expand All @@ -112,11 +112,11 @@ macro_rules! bench_insert {

bench_suite!(
bench_insert,
insert_foldhash_serial,
insert_rapidhash_serial,
insert_std_serial,
insert_foldhash_highbits,
insert_rapidhash_highbits,
insert_std_highbits,
insert_foldhash_random,
insert_rapidhash_random,
insert_std_random
);

Expand All @@ -137,11 +137,11 @@ macro_rules! bench_grow_insert {

bench_suite!(
bench_grow_insert,
grow_insert_foldhash_serial,
grow_insert_rapidhash_serial,
grow_insert_std_serial,
grow_insert_foldhash_highbits,
grow_insert_rapidhash_highbits,
grow_insert_std_highbits,
grow_insert_foldhash_random,
grow_insert_rapidhash_random,
grow_insert_std_random
);

Expand Down Expand Up @@ -173,11 +173,11 @@ macro_rules! bench_insert_erase {

bench_suite!(
bench_insert_erase,
insert_erase_foldhash_serial,
insert_erase_rapidhash_serial,
insert_erase_std_serial,
insert_erase_foldhash_highbits,
insert_erase_rapidhash_highbits,
insert_erase_std_highbits,
insert_erase_foldhash_random,
insert_erase_rapidhash_random,
insert_erase_std_random
);

Expand All @@ -202,11 +202,11 @@ macro_rules! bench_lookup {

bench_suite!(
bench_lookup,
lookup_foldhash_serial,
lookup_rapidhash_serial,
lookup_std_serial,
lookup_foldhash_highbits,
lookup_rapidhash_highbits,
lookup_std_highbits,
lookup_foldhash_random,
lookup_rapidhash_random,
lookup_std_random
);

Expand All @@ -231,11 +231,11 @@ macro_rules! bench_lookup_fail {

bench_suite!(
bench_lookup_fail,
lookup_fail_foldhash_serial,
lookup_fail_rapidhash_serial,
lookup_fail_std_serial,
lookup_fail_foldhash_highbits,
lookup_fail_rapidhash_highbits,
lookup_fail_std_highbits,
lookup_fail_foldhash_random,
lookup_fail_rapidhash_random,
lookup_fail_std_random
);

Expand Down Expand Up @@ -336,11 +336,11 @@ macro_rules! bench_iter {

bench_suite!(
bench_iter,
iter_foldhash_serial,
iter_rapidhash_serial,
iter_std_serial,
iter_foldhash_highbits,
iter_rapidhash_highbits,
iter_std_highbits,
iter_foldhash_random,
iter_rapidhash_random,
iter_std_random
);

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

/// Default hasher for [`HashMap`] and [`HashSet`].
#[cfg(feature = "default-hasher")]
pub type DefaultHashBuilder = foldhash::fast::RandomState;
pub type DefaultHashBuilder = rapidhash::fast::RandomState;

/// Dummy default hasher for [`HashMap`] and [`HashSet`].
#[cfg(not(feature = "default-hasher"))]
Expand Down
4 changes: 2 additions & 2 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub use crate::raw_entry::*;

/// A hash map implemented with quadratic probing and SIMD lookup.
///
/// The default hashing algorithm is currently [`foldhash`], though this is
/// The default hashing algorithm is currently [`rapidhash`], though this is
/// subject to change at any point in the future. This hash function is very
/// fast for all types of keys, but this algorithm will typically *not* protect
/// against attacks such as HashDoS.
Expand Down Expand Up @@ -142,7 +142,7 @@ pub use crate::raw_entry::*;
/// [`with_hasher`]: #method.with_hasher
/// [`with_capacity_and_hasher`]: #method.with_capacity_and_hasher
/// [`fnv`]: https://crates.io/crates/fnv
/// [`foldhash`]: https://crates.io/crates/foldhash
/// [`rapidhash`]: https://crates.io/crates/rapidhash
///
/// ```
/// use hashbrown::HashMap;
Expand Down
Loading