Skip to content

Commit

Permalink
Use unsafe code resembling slice::as_chunks to further speed up small…
Browse files Browse the repository at this point in the history
… strings.
  • Loading branch information
adamreichold committed Jan 18, 2024
1 parent d065b7f commit 6f0afc1
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ mod random_state;

mod seeded_state;

use core::convert::TryInto;
use core::default::Default;
#[cfg(feature = "std")]
use core::hash::BuildHasherDefault;
use core::hash::Hasher;
use core::mem::size_of;
use core::ops::BitXor;
use core::slice::from_raw_parts;
#[cfg(feature = "std")]
use std::collections::{HashMap, HashSet};

Expand Down Expand Up @@ -103,7 +103,7 @@ impl FxHasher {

impl Hasher for FxHasher {
#[inline]
fn write(&mut self, mut bytes: &[u8]) {
fn write(&mut self, bytes: &[u8]) {
const SIZE: usize = {
let size = size_of::<usize>();
assert!(size != 0);
Expand All @@ -112,15 +112,23 @@ impl Hasher for FxHasher {

let mut hash = self.clone();

while bytes.len() >= SIZE {
let (chunk, rest) = bytes.split_at(SIZE);
hash.add_to_hash(usize::from_ne_bytes(chunk.try_into().unwrap()));
bytes = rest;
let quot = bytes.len() / SIZE;
let rem = bytes.len() % SIZE;

// FIXME: use slice::as_chunks when stabilized, c.f. https://github.com/rust-lang/rust/issues/74985
let ptr = bytes.as_ptr();
// SAFETY: SIZE != 0 and quot * SIZE = bytes.len() / SIZE * SIZE <= bytes.len()
let chunks: &[[u8; SIZE]] = unsafe { from_raw_parts(ptr.cast(), quot) };
// SAFETY: quot * SIZE + rem = bytes.len() / SIZE * SIZE + bytes.len() % SIZE = rem + rem = bytes.len()
let rest = unsafe { from_raw_parts(ptr.add(quot * SIZE), rem) };

for chunk in chunks {
hash.add_to_hash(usize::from_ne_bytes(*chunk));
}

if !bytes.is_empty() {
if rem != 0 {
let mut chunk = 0;
for &byte in bytes {
for &byte in rest {
chunk = chunk << 8 | byte as usize;
}
hash.add_to_hash(chunk);
Expand Down

0 comments on commit 6f0afc1

Please sign in to comment.