Skip to content

Commit d3174ce

Browse files
committed
collections: Hash VecDeque in its slice parts
Use .as_slices() for a more efficient code path in VecDeque's Hash impl. This still hashes the elements in the same order. Before/after timing of VecDeque hashing 1024 elements of u8 and u64 shows that the vecdeque now can match the Vec (test_hashing_vec_of_u64 is the Vec run). before test test_hashing_u64 ... bench: 14,031 ns/iter (+/- 236) = 583 MB/s test test_hashing_u8 ... bench: 7,887 ns/iter (+/- 65) = 129 MB/s test test_hashing_vec_of_u64 ... bench: 6,578 ns/iter (+/- 76) = 1245 MB/s after running 5 tests test test_hashing_u64 ... bench: 6,495 ns/iter (+/- 52) = 1261 MB/s test test_hashing_u8 ... bench: 851 ns/iter (+/- 16) = 1203 MB/s test test_hashing_vec_of_u64 ... bench: 6,499 ns/iter (+/- 59) = 1260 MB/s
1 parent 46dcffd commit d3174ce

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

src/libcollections/vec_deque.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1994,9 +1994,9 @@ impl<A: Ord> Ord for VecDeque<A> {
19941994
impl<A: Hash> Hash for VecDeque<A> {
19951995
fn hash<H: Hasher>(&self, state: &mut H) {
19961996
self.len().hash(state);
1997-
for elt in self {
1998-
elt.hash(state);
1999-
}
1997+
let (a, b) = self.as_slices();
1998+
Hash::hash_slice(a, state);
1999+
Hash::hash_slice(b, state);
20002000
}
20012001
}
20022002

src/libcollectionstest/vec_deque.rs

+19
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,25 @@ fn test_hash() {
605605
assert!(::hash(&x) == ::hash(&y));
606606
}
607607

608+
#[test]
609+
fn test_hash_after_rotation() {
610+
// test that two deques hash equal even if elements are laid out differently
611+
let len = 28;
612+
let mut ring: VecDeque<i32> = (0..len as i32).collect();
613+
let orig = ring.clone();
614+
for _ in 0..ring.capacity() {
615+
// shift values 1 step to the right by pop, sub one, push
616+
ring.pop_front();
617+
for elt in &mut ring {
618+
*elt -= 1;
619+
}
620+
ring.push_back(len - 1);
621+
assert_eq!(::hash(&orig), ::hash(&ring));
622+
assert_eq!(orig, ring);
623+
assert_eq!(ring, orig);
624+
}
625+
}
626+
608627
#[test]
609628
fn test_ord() {
610629
let x = VecDeque::new();

0 commit comments

Comments
 (0)