Skip to content

Commit

Permalink
collections: Hash VecDeque in its slice parts
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bluss committed Jan 26, 2016
1 parent 46dcffd commit d3174ce
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/libcollections/vec_deque.rs
Expand Up @@ -1994,9 +1994,9 @@ impl<A: Ord> Ord for VecDeque<A> {
impl<A: Hash> Hash for VecDeque<A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.len().hash(state);
for elt in self {
elt.hash(state);
}
let (a, b) = self.as_slices();
Hash::hash_slice(a, state);
Hash::hash_slice(b, state);
}
}

Expand Down
19 changes: 19 additions & 0 deletions src/libcollectionstest/vec_deque.rs
Expand Up @@ -605,6 +605,25 @@ fn test_hash() {
assert!(::hash(&x) == ::hash(&y));
}

#[test]
fn test_hash_after_rotation() {
// test that two deques hash equal even if elements are laid out differently
let len = 28;
let mut ring: VecDeque<i32> = (0..len as i32).collect();
let orig = ring.clone();
for _ in 0..ring.capacity() {
// shift values 1 step to the right by pop, sub one, push
ring.pop_front();
for elt in &mut ring {
*elt -= 1;
}
ring.push_back(len - 1);
assert_eq!(::hash(&orig), ::hash(&ring));
assert_eq!(orig, ring);
assert_eq!(ring, orig);
}
}

#[test]
fn test_ord() {
let x = VecDeque::new();
Expand Down

0 comments on commit d3174ce

Please sign in to comment.