mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: a better fallback hash
For arm and powerpc, as well as x86 without aes instructions. Contains a mixture of ideas from cityhash and xxhash. Compared to our old fallback on ARM, it's ~no slower on small objects and up to ~50% faster on large objects. More importantly, it is a much better hash function and thus has less chance of bad behavior. Fixes #8737 benchmark old ns/op new ns/op delta BenchmarkHash5 173 181 +4.62% BenchmarkHash16 252 212 -15.87% BenchmarkHash64 575 419 -27.13% BenchmarkHash1024 7173 3995 -44.31% BenchmarkHash65536 516940 313173 -39.42% BenchmarkHashStringSpeed 300 279 -7.00% BenchmarkHashBytesSpeed 478 424 -11.30% BenchmarkHashInt32Speed 217 207 -4.61% BenchmarkHashInt64Speed 262 231 -11.83% BenchmarkHashStringArraySpeed 609 631 +3.61% Change-Id: I0a9335028f32b10ad484966e3019987973afd3eb Reviewed-on: https://go-review.googlesource.com/1360 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
fbc56cf050
commit
cda0ea1c0e
7 changed files with 229 additions and 32 deletions
|
|
@ -72,8 +72,6 @@ var algarray = [alg_max]typeAlg{
|
|||
alg_CPLX128: {c128hash, c128equal},
|
||||
}
|
||||
|
||||
const nacl = GOOS == "nacl"
|
||||
|
||||
var useAeshash bool
|
||||
|
||||
// in asm_*.s
|
||||
|
|
@ -82,22 +80,9 @@ func aeshash32(p unsafe.Pointer, s, h uintptr) uintptr
|
|||
func aeshash64(p unsafe.Pointer, s, h uintptr) uintptr
|
||||
func aeshashstr(p unsafe.Pointer, s, h uintptr) uintptr
|
||||
|
||||
func memhash(p unsafe.Pointer, s, h uintptr) uintptr {
|
||||
if !nacl && useAeshash {
|
||||
return aeshash(p, s, h)
|
||||
}
|
||||
|
||||
h ^= c0
|
||||
for s > 0 {
|
||||
h = (h ^ uintptr(*(*byte)(p))) * c1
|
||||
p = add(p, 1)
|
||||
s--
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func strhash(a unsafe.Pointer, s, h uintptr) uintptr {
|
||||
return memhash((*stringStruct)(a).str, uintptr(len(*(*string)(a))), h)
|
||||
x := (*stringStruct)(a)
|
||||
return memhash(x.str, uintptr(x.len), h)
|
||||
}
|
||||
|
||||
// NOTE: Because NaN != NaN, a map can contain any
|
||||
|
|
@ -267,10 +252,6 @@ func ifaceeq(p, q interface {
|
|||
}
|
||||
|
||||
// Testing adapters for hash quality tests (see hash_test.go)
|
||||
func haveGoodHash() bool {
|
||||
return useAeshash
|
||||
}
|
||||
|
||||
func stringHash(s string, seed uintptr) uintptr {
|
||||
return algarray[alg_STRING].hash(noescape(unsafe.Pointer(&s)), unsafe.Sizeof(s), seed)
|
||||
}
|
||||
|
|
@ -315,7 +296,7 @@ const hashRandomBytes = ptrSize / 4 * 64
|
|||
var aeskeysched [hashRandomBytes]byte
|
||||
|
||||
func init() {
|
||||
if theGoos == "nacl" {
|
||||
if GOOS == "nacl" {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue