Skip to content

Instantly share code, notes, and snippets.

@huydx
Created July 7, 2020 13:24
Show Gist options
  • Save huydx/dcb79dd38a2c0e0e2f04ac5cc00e80c5 to your computer and use it in GitHub Desktop.
Save huydx/dcb79dd38a2c0e0e2f04ac5cc00e80c5 to your computer and use it in GitHub Desktop.
//go:noescape
//go:linkname memhash runtime.memhash
func memhash(p unsafe.Pointer, h, s uintptr) uintptr
type stringStruct struct {
str unsafe.Pointer
len int
}
// MemHash is the hash function used by go map, it utilizes available hardware instructions(behaves
// as aeshash if aes instruction is available).
// NOTE: The hash seed changes for every process. So, this cannot be used as a persistent hash.
func MemHash(data []byte) uint64 {
ss := (*stringStruct)(unsafe.Pointer(&data))
return uint64(memhash(ss.str, 0, uintptr(ss.len)))
}
func Benchmark_MemHash(b *testing.B) {
seed := ""
for i := 0; i < 100; i++ {
seed += fmt.Sprintf("%v",i)
}
for i := 0; i <= b.N; i++ {
MemHash([]byte(seed))
}
}
func Benchmark_FNV(b *testing.B) {
seed := ""
for i := 0; i < 100; i++ {
seed += fmt.Sprintf("%v",i)
}
hash := fnv.New64()
for i := 0; i <= b.N; i++ {
hash.Sum([]byte(seed))
hash.Sum64()
}
}
@huydx
Copy link
Author

huydx commented Jul 7, 2020

for string len 0:

Benchmark_MemHash-8   	16153923	        76.4 ns/op
Benchmark_FNV-8       	 7797662	       155 ns/op

for string len 1000

Benchmark_MemHash-8   	 2039546	       590 ns/op
Benchmark_FNV-8       	 2523384	       470 ns/op

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment