rust-lang / hashbrown

Rust port of Google's SwissTable hash map
https://rust-lang.github.io/hashbrown
Apache License 2.0
2.43k stars 288 forks source link

Returning / Accepting hash codes #455

Open YuriGor opened 1 year ago

YuriGor commented 1 year ago

Hello everyone, how much of cpu is eaten by make_hash with default hasher? Would it make sense to let user cache hashcode and let later reuse it if hse is able to? I could imagine alternative insert / get methods which accept/return hash code alongside with a key.

e.g.

pub fn insert(&mut self, k: K, v: V) -> Option<V> {
    let hash = make_hash::<K, S>(&self.hash_builder, &k); // <-- we could let user pass it as arg if it's override and return to let user cache it
    let hasher = make_hasher::<_, V, S>(&self.hash_builder);
    match self
        .table
        .find_or_find_insert_slot(hash, equivalent_key(&k), hasher)
    {
        Ok(bucket) => Some(mem::replace(unsafe { &mut bucket.as_mut().1 }, v)),
        Err(slot) => {
            unsafe {
                self.table.insert_in_slot(hash, slot, (k, v));
            }
            None
        }
    }
}
fn get_inner<Q: ?Sized>(&self, k: &Q) -> Option<&(K, V)>
where
    Q: Hash + Equivalent<K>,
{
    if self.table.is_empty() {
        None
    } else {
        let hash = make_hash::<Q, S>(&self.hash_builder, k);// <-- same here, optionally accept as arg instead of recalculating and return to let user cache it
        self.table.get(hash, equivalent_key(k))
    }
}

On reddit @thermiter36 suggested raw_entry API but I honestly didn't get it how can I use it for hash code caching, maybe it's easy if one knows how? pls discuss.