Created
December 31, 2020 08:24
-
-
Save EddieIvan01/17939c44b52a7572f4c4bf21a615f2a6 to your computer and use it in GitHub Desktop.
They all used unsafe raw pointer operations, so they are more fast then existing Rust implementations (2020.12.31)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn fmix32(mut h: u32) -> u32 { | |
h ^= h >> 16; | |
h = h.wrapping_mul(0x85ebca6b); | |
h ^= h >> 13; | |
h = h.wrapping_mul(0xc2b2ae35); | |
h ^= h >> 16; | |
h | |
} | |
fn get_32_block(ptr: *const u8) -> u32 { | |
unsafe { *mem::transmute::<*const u8, *const u32>(ptr) } | |
} | |
fn murmurhash3_x86_32(bs: &[u8]) -> u32 { | |
let len = bs.len() as u32; | |
let rem = len & 3; | |
let mut ptr = bs.as_ptr(); | |
let mut h = 0xf1f2f3f4; | |
let _: Vec<_> = (0..(len >> 2)) | |
.map(|_| unsafe { | |
let mut k = get_32_block(ptr); | |
k = k.wrapping_mul(0xcc9e2d51); | |
k = k.rotate_left(15); | |
k = k.wrapping_mul(0x1b873593); | |
h ^= k; | |
h = h.rotate_left(13); | |
h = h.wrapping_mul(5); | |
h = h.wrapping_add(0xe6546b64); | |
ptr = ptr.offset(4); | |
}) | |
.collect(); | |
let mut k = 0u32; | |
if rem == 3 { | |
k ^= unsafe { (*ptr.offset(2) as u32) << 16 }; | |
} | |
if rem >= 2 { | |
k ^= unsafe { (*ptr.offset(1) as u32) << 8 }; | |
} | |
if rem >= 1 { | |
k ^= unsafe { *ptr.offset(0) as u32 }; | |
k = k.wrapping_mul(0xcc9e2d51); | |
k = k.rotate_left(15); | |
k = k.wrapping_mul(0x1b873593); | |
h ^= k; | |
} | |
h ^= bs.len() as u32; | |
h = fmix32(h); | |
return h; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn get16bits(ptr: *const u8) -> Wrapping<u32> { | |
unsafe { Wrapping(*mem::transmute::<*const u8, *const u16>(ptr) as u32) } | |
} | |
fn super_fast_hash(s: &str) -> u32 { | |
let len = s.len() as u32; | |
if len == 0 { | |
return 0; | |
} | |
let rem = len & 3; | |
let mut hsh = Wrapping(len); | |
let mut tmp = Wrapping(0_u32); | |
let mut ptr = s.as_ptr(); | |
let _: Vec<_> = (0..(len >> 2)) | |
.map(|_| unsafe { | |
hsh += get16bits(ptr); | |
tmp = (get16bits(ptr.offset(2)) << 11) ^ hsh; | |
hsh = (hsh << 16) ^ tmp; | |
ptr = ptr.offset(4); | |
hsh += hsh >> 11; | |
}) | |
.collect(); | |
match rem { | |
1 => unsafe { | |
hsh += Wrapping(*ptr as u32); | |
hsh ^= hsh << 10; | |
hsh += hsh >> 1; | |
}, | |
2 => { | |
hsh += get16bits(ptr); | |
hsh ^= hsh << 11; | |
hsh += hsh >> 17; | |
} | |
3 => unsafe { | |
hsh += get16bits(ptr); | |
hsh ^= hsh << 16; | |
hsh ^= Wrapping(*ptr.offset(2) as u32) << 18; | |
hsh += hsh >> 11; | |
}, | |
_ => (), | |
} | |
hsh ^= hsh << 3; | |
hsh += hsh >> 5; | |
hsh ^= hsh << 4; | |
hsh += hsh >> 17; | |
hsh ^= hsh << 25; | |
hsh += hsh >> 6; | |
hsh.0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment