Skip to content

Commit

Permalink
Add write_* methods for DefaultHasher, SipHasher, SipHasher13
Browse files Browse the repository at this point in the history
…, `sip::Hasher`.

`sip::Hasher::short_write` is currently unused. It is called by
`sip::Hasher::write_{u8,usize}`, but those methods are also unused,
because `DefaultHasher`, `SipHasher` and `SipHasher13` don't implement
any of the `write_xyz` methods, so all their write operations end up
calling `sip::Hasher::write`.

I confirmed this by inserting a `panic!` in `sip::Hasher::short_write`
and running the tests -- they all passed.

This commit adds all the `write_xyz` methods to `DefaultHasher`,
`SipHasher`, `SipHasher13` and `sip::Hasher`, which means that
`short_write` will be used for all of them.

(I haven't properly implemented 128-bit writes in `sip::Hasher` and
`SipHasher128`. That could be a follow-up if something thinks it is
important.)

Some microbenchmarks I wrote show that this commit speeds up default
hashing of integers by about 2.5x, and can speed up hash tables that use
`DefaultHasher` and have keys that contain integers by up to 30%, though
the exact amount depends heavily on the details of the keys and how the
table is used. This makes default `Hash{Map,Set}` much more likely to be
competitive with `FxHash{Map,Set}`.
  • Loading branch information
nnethercote committed Feb 23, 2020
1 parent f272983 commit 96c4e42
Show file tree
Hide file tree
Showing 3 changed files with 228 additions and 0 deletions.
164 changes: 164 additions & 0 deletions src/libcore/hash/sip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,66 @@ impl<S: Sip> Hasher<S> {

#[stable(feature = "rust1", since = "1.0.0")]
impl super::Hasher for SipHasher {
#[inline]
fn write_u8(&mut self, i: u8) {
self.0.hasher.write_u8(i);
}

#[inline]
fn write_u16(&mut self, i: u16) {
self.0.hasher.write_u16(i);
}

#[inline]
fn write_u32(&mut self, i: u32) {
self.0.hasher.write_u32(i);
}

#[inline]
fn write_u64(&mut self, i: u64) {
self.0.hasher.write_u64(i);
}

#[inline]
fn write_u128(&mut self, i: u128) {
self.0.hasher.write_u128(i);
}

#[inline]
fn write_usize(&mut self, i: usize) {
self.0.hasher.write_usize(i);
}

#[inline]
fn write_i8(&mut self, i: i8) {
self.0.hasher.write_i8(i);
}

#[inline]
fn write_i16(&mut self, i: i16) {
self.0.hasher.write_i16(i);
}

#[inline]
fn write_i32(&mut self, i: i32) {
self.0.hasher.write_i32(i);
}

#[inline]
fn write_i64(&mut self, i: i64) {
self.0.hasher.write_i64(i);
}

#[inline]
fn write_i128(&mut self, i: i128) {
self.0.hasher.write_i128(i);
}

#[inline]
fn write_isize(&mut self, i: isize) {
self.0.hasher.write_isize(i);
}

#[inline]
fn write(&mut self, msg: &[u8]) {
self.0.hasher.write(msg)
Expand All @@ -309,6 +369,66 @@ impl super::Hasher for SipHasher {

#[unstable(feature = "hashmap_internals", issue = "none")]
impl super::Hasher for SipHasher13 {
#[inline]
fn write_u8(&mut self, i: u8) {
self.hasher.write_u8(i);
}

#[inline]
fn write_u16(&mut self, i: u16) {
self.hasher.write_u16(i);
}

#[inline]
fn write_u32(&mut self, i: u32) {
self.hasher.write_u32(i);
}

#[inline]
fn write_u64(&mut self, i: u64) {
self.hasher.write_u64(i);
}

#[inline]
fn write_u128(&mut self, i: u128) {
self.hasher.write_u128(i);
}

#[inline]
fn write_usize(&mut self, i: usize) {
self.hasher.write_usize(i);
}

#[inline]
fn write_i8(&mut self, i: i8) {
self.hasher.write_i8(i);
}

#[inline]
fn write_i16(&mut self, i: i16) {
self.hasher.write_i16(i);
}

#[inline]
fn write_i32(&mut self, i: i32) {
self.hasher.write_i32(i);
}

#[inline]
fn write_i64(&mut self, i: i64) {
self.hasher.write_i64(i);
}

#[inline]
fn write_i128(&mut self, i: i128) {
self.hasher.write_i128(i);
}

#[inline]
fn write_isize(&mut self, i: isize) {
self.hasher.write_isize(i);
}

#[inline]
fn write(&mut self, msg: &[u8]) {
self.hasher.write(msg)
Expand All @@ -326,11 +446,55 @@ impl<S: Sip> super::Hasher for Hasher<S> {
self.short_write(i, i as u64);
}

#[inline]
fn write_u16(&mut self, i: u16) {
self.short_write(i, i.to_le() as u64);
}

#[inline]
fn write_u32(&mut self, i: u32) {
self.short_write(i, i.to_le() as u64);
}

#[inline]
fn write_u64(&mut self, i: u64) {
self.short_write(i, i.to_le() as u64);
}

// `write_u128` is currently unimplemented.

#[inline]
fn write_usize(&mut self, i: usize) {
self.short_write(i, i.to_le() as u64);
}

#[inline]
fn write_i8(&mut self, i: i8) {
self.short_write(i, i as u8 as u64);
}

#[inline]
fn write_i16(&mut self, i: i16) {
self.short_write(i, (i as u16).to_le() as u64);
}

#[inline]
fn write_i32(&mut self, i: i32) {
self.short_write(i, (i as u32).to_le() as u64);
}

#[inline]
fn write_i64(&mut self, i: i64) {
self.short_write(i, (i as u64).to_le() as u64);
}

// `write_i128` is currently unimplemented.

#[inline]
fn write_isize(&mut self, i: isize) {
self.short_write(i, (i as usize).to_le() as u64);
}

#[inline]
fn write(&mut self, msg: &[u8]) {
let length = msg.len();
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_data_structures/sip128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ impl Hasher for SipHasher128 {
self.short_write(i, i.to_le() as u64);
}

// `write_u128` is currently unimplemented.

#[inline]
fn write_usize(&mut self, i: usize) {
self.short_write(i, i.to_le() as u64);
Expand All @@ -260,6 +262,8 @@ impl Hasher for SipHasher128 {
self.short_write(i, (i as u64).to_le() as u64);
}

// `write_i128` is currently unimplemented.

#[inline]
fn write_isize(&mut self, i: isize) {
self.short_write(i, (i as usize).to_le() as u64);
Expand Down
60 changes: 60 additions & 0 deletions src/libstd/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,66 @@ impl Default for DefaultHasher {

#[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
impl Hasher for DefaultHasher {
#[inline]
fn write_u8(&mut self, i: u8) {
self.0.write_u8(i);
}

#[inline]
fn write_u16(&mut self, i: u16) {
self.0.write_u16(i);
}

#[inline]
fn write_u32(&mut self, i: u32) {
self.0.write_u32(i);
}

#[inline]
fn write_u64(&mut self, i: u64) {
self.0.write_u64(i);
}

#[inline]
fn write_u128(&mut self, i: u128) {
self.0.write_u128(i);
}

#[inline]
fn write_usize(&mut self, i: usize) {
self.0.write_usize(i);
}

#[inline]
fn write_i8(&mut self, i: i8) {
self.0.write_i8(i);
}

#[inline]
fn write_i16(&mut self, i: i16) {
self.0.write_i16(i);
}

#[inline]
fn write_i32(&mut self, i: i32) {
self.0.write_i32(i);
}

#[inline]
fn write_i64(&mut self, i: i64) {
self.0.write_i64(i);
}

#[inline]
fn write_i128(&mut self, i: i128) {
self.0.write_i128(i);
}

#[inline]
fn write_isize(&mut self, i: isize) {
self.0.write_isize(i);
}

#[inline]
fn write(&mut self, msg: &[u8]) {
self.0.write(msg)
Expand Down

0 comments on commit 96c4e42

Please sign in to comment.