Skip to content

Instantly share code, notes, and snippets.

@arthurprs
Created July 11, 2016 09:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arthurprs/88eef0b57b9f8341c54e2d82ec775698 to your computer and use it in GitHub Desktop.
Save arthurprs/88eef0b57b9f8341c54e2d82ec775698 to your computer and use it in GitHub Desktop.
#![feature(sip_hash_13)]
use std::time;
use std::collections::HashMap;
use std::hash::{BuildHasher, BuildHasherDefault};
use std::hash::{SipHasher13, SipHasher24};
type TTTT = u32;
fn main() {
let a = time::SystemTime::now();
let mut m = HashMap::<TTTT, TTTT, _>::with_hasher(
BuildHasherDefault::<SipHasher13>::default()
);
for i in 0..200_000_000 {
*m.entry(i % 100_000).or_insert(0) += 1;
}
println!("{}", m[&40000]);
println!("SIP13 {:?}", a.elapsed().unwrap());
let a = time::SystemTime::now();
let mut m = HashMap::<TTTT, TTTT, _>::with_hasher(
BuildHasherDefault::<SipHasher24>::default()
);
for i in 0..200_000_000 {
*m.entry(i % 100_000).or_insert(0) += 1;
}
println!("{}", m[&40000]);
println!("SIP24 {:?}", a.elapsed().unwrap());
let a = time::SystemTime::now();
let mut m = HashMap::<TTTT, TTTT, _>::with_hasher(
BuildHasherDefault::<fnv::FnvHasher>::default()
);
for i in 0..200_000_000 {
*m.entry(i % 100_000).or_insert(0) += 1;
}
println!("{}", m[&40000]);
println!("FNV {:?}", a.elapsed().unwrap());
let a = time::SystemTime::now();
let mut m = HashMap::<TTTT, TTTT, _>::with_hasher(
BuildHasherDefault::<simple::SimpleHasher>::default()
);
for i in 0..200_000_000 {
*m.entry(i % 100_000).or_insert(0) += 1;
}
println!("{}", m[&40000]);
println!("Simple {:?}", a.elapsed().unwrap());
}
mod fnv {
use std::hash::Hasher;
pub struct FnvHasher(u64);
impl Default for FnvHasher {
#[inline]
fn default() -> FnvHasher {
FnvHasher(0xcbf29ce484222325)
}
}
impl Hasher for FnvHasher {
#[inline]
fn finish(&self) -> u64 {
self.0
}
#[inline]
fn write(&mut self, bytes: &[u8]) {
let FnvHasher(mut hash) = *self;
for byte in bytes.iter() {
hash = hash ^ (*byte as u64);
hash = hash.wrapping_mul(0x100000001b3);
}
*self = FnvHasher(hash);
}
}
}
mod simple {
use std::hash::Hasher;
pub struct SimpleHasher(u64);
#[inline]
fn load_u64_le(buf: &[u8], len: usize) -> u64 {
use std::ptr;
debug_assert!(len <= buf.len());
let mut data = 0u64;
unsafe {
ptr::copy_nonoverlapping(buf.as_ptr(), &mut data as *mut _ as *mut u8, len);
}
data.to_le()
}
impl Default for SimpleHasher {
#[inline]
fn default() -> SimpleHasher {
SimpleHasher(0)
}
}
impl Hasher for SimpleHasher {
#[inline]
fn finish(&self) -> u64 {
self.0
}
#[inline]
fn write(&mut self, bytes: &[u8]) {
*self = SimpleHasher(load_u64_le(bytes, bytes.len()));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment