mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
perf: improve {Dict, Set}::hash
This commit is contained in:
parent
f862a3f13a
commit
037712b282
2 changed files with 19 additions and 7 deletions
|
@ -36,13 +36,22 @@ 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 len = self.len();
|
||||
len.hash(state);
|
||||
if len <= 1 {
|
||||
for (key, val) in self.iter() {
|
||||
key.hash(state);
|
||||
val.hash(state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let mut v = self
|
||||
.iter()
|
||||
.map(|(key, val)| (get_hash(key), key, val))
|
||||
.map(|(key, val)| (get_hash(key), val))
|
||||
.collect::<Vec<_>>();
|
||||
v.sort_by_key(|(h, _, _)| *h);
|
||||
for (_, key, val) in v.iter() {
|
||||
key.hash(state);
|
||||
v.sort_unstable_by_key(|(h, _)| *h);
|
||||
for (h, val) in v.iter() {
|
||||
state.write_usize(*h);
|
||||
val.hash(state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue