Home
Rust
HashMap with_hasher Example
Updated Nov 12, 2024
Dot Net Perls
HashMap with_hasher. In Rust we can specify a hash function for the HashMap (and HashSet) structs. By doing this, we can improve performance for programs that use hashtable lookups.
HashMap
To specify a custom Hasher, we use with_hasher (or with_hasher_and_capacity). Then, we use the HashMap like we normally do. The HashMap has a different type (the Hasher is the third generic type).
Example. This program uses 2 different Hasher arguments to create HashMaps. It accesses the Hasher from the standard library, and then uses an external crate (ahash).
Part 1 We use the with_hasher function to create a HashMap. We use the Hasher from the standard library—this is the same as calling new().
Part 2 Ahash is an optimized hash function in an external crate (the ahash crate). We must add the dependency with cargo first.
use std::collections::*; fn main() { // Part 1: use HashMap with default hasher from standard library. let mut h = HashMap::with_hasher(std::hash::RandomState::default()); h.insert("bird", 10); if let Some(result) = h.get("bird") { println!("{result}"); } // Part 2: use HashMap with ahash Hasher (add ahash dependency first). let mut h = HashMap::with_hasher(ahash::RandomState::default()); h.insert("bird", 10); if let Some(result) = h.get("bird") { println!("{result}"); } }
10 10
Type example. When we create a HashMap with a custom Hasher (using with_hasher), the type of the HashMap is affected. The custom Hasher type is the third generic type of a HashMap.
Tip It is possible to use a type alias for your custom hasher, and use that throughout your program for your HashMap types.
use std::collections::*; // Part 1: the type of a HashMap with a custom hasher has 3 generic arguments. struct Example { h: HashMap<String, usize, ahash::RandomState>, } fn main() { // Part 2: create the HashMap. let mut h = HashMap::with_hasher(ahash::RandomState::default()); h.insert("cat".to_string(), 100usize); // Part 3: store the HashMap within another struct. let example = Example { h }; println!("{}", example.h.len()); }
1
Benchmark. It it worth the effort to replace the default hash function in Rust programs? This benchmark aims to determine if the "ahash" crate is worth using.
Version 1 We create a HashMap with the default hasher—this could just be a call to new().
Version 2 We use the ahash Hasher, which is also called RandomState. We perform the same lookups in both versions of the code.
Result For just doing lookups, the ahash crate's Hasher is many times faster than the default Hasher in Rust as of 2024.
use std::collections::*; use std::time::*; fn main() { let mut map = HashMap::with_hasher(std::hash::RandomState::default()); map.insert("bird", 0); map.insert("frog", 0); map.insert("dog", 0); let mut map2 = HashMap::with_hasher(ahash::RandomState::default()); map2.insert("bird", 0); map2.insert("frog", 0); map2.insert("dog", 0); if let Ok(max) = "100000000".parse::<usize>() { let mut count = 0; // Version 1: use HashMap with standard library hasher. let t0 = Instant::now(); for _ in 0..max { if let Some(_) = map.get("frog") { count += 1; } } println!("{} ms", t0.elapsed().as_millis()); // Version 2: use HashMap with ahash hasher (from crate). let t1 = Instant::now(); for _ in 0..max { if let Some(_) = map2.get("frog") { count += 1; } } println!("{} ms", t1.elapsed().as_millis()); println!("{}", count); } }
779 ms 102 ms 200000000
Summary. HashMaps and HashSets in Rust are well-optimized, but with a custom Hasher from a crate such as Ahash we can achieve even higher performance. For some programs this is a big speedup.
Dot Net Perls is a collection of pages with code examples, which are updated to stay current. Programming is an art, and it can be learned from examples.
Donate to this site to help offset the costs of running the server. Sites like this will cease to exist if there is no financial support for them.
Sam Allen is passionate about computer languages, and he maintains 100% of the material available on this website. He hopes it makes the world a nicer place.
This page was last updated on Nov 12, 2024 (new).
Home
Changes
© 2007-2025 Sam Allen