Skip to content

Commit

Permalink
perf: improve {Dict, Set}::hash
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Oct 3, 2024
1 parent f862a3f commit e7ff9f4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
25 changes: 17 additions & 8 deletions crates/erg_common/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,23 @@ impl<K: Hash + Eq + Immutable, V: Hash + Eq> Eq for Dict<K, V> {}

impl<K: Hash, V: Hash> Hash for Dict<K, V> {
fn hash<H: Hasher>(&self, state: &mut H) {
let mut v = self
.iter()
.map(|(key, val)| (get_hash(key), key, val))
.collect::<Vec<_>>();
v.sort_by_key(|(h, _, _)| *h);
for (_, key, val) in v.iter() {
key.hash(state);
val.hash(state);
let len = self.len();
len.hash(state);
if len <= 1 {
for (key, val) in self.iter() {
key.hash(state);
val.hash(state);
}
} else {
let mut v = self
.iter()
.map(|(key, val)| (get_hash(key), val))
.collect::<Vec<_>>();
v.sort_unstable_by_key(|(h, _)| *h);
for (h, val) in v.iter() {
state.write_usize(*h);
val.hash(state);
}
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions crates/erg_common/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ impl<T> Default for Set<T> {

impl<T: Hash> Hash for Set<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
let mut v = self.iter().map(get_hash).collect::<Vec<_>>();
v.sort();
v.hash(state);
self.len().hash(state);
let sum = self
.iter()
.map(get_hash)
.fold(0usize, |acc, x| acc.wrapping_add(x));
sum.hash(state);
}
}

Expand Down

0 comments on commit e7ff9f4

Please sign in to comment.