internal/deephash: use MapIter.Set{Key,Value}
To get the benefit of this optimization requires help from the Go toolchain.
The changes are upstream at https://golang.org/cl/320929,
and have been pulled into the Tailscale fork at
728ecc58fd
.
It also requires building with the build tag tailscale_go.
name old time/op new time/op delta
Hash-8 14.0µs ± 0% 13.6µs ± 0% -2.88% (p=0.008 n=5+5)
HashMapAcyclic-8 24.3µs ± 1% 21.2µs ± 1% -12.47% (p=0.008 n=5+5)
name old alloc/op new alloc/op delta
Hash-8 2.16kB ± 0% 1.58kB ± 0% -27.01% (p=0.008 n=5+5)
HashMapAcyclic-8 2.53kB ± 0% 0.15kB ± 0% -93.99% (p=0.008 n=5+5)
name old allocs/op new allocs/op delta
Hash-8 77.0 ± 0% 49.0 ± 0% -36.36% (p=0.008 n=5+5)
HashMapAcyclic-8 202 ± 0% 4 ± 0% -98.02% (p=0.008 n=5+5)
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
setkey
This commit is contained in:
parent
020e904f4e
commit
a2d7a2aeb1
|
@ -240,12 +240,16 @@ func hashMapAcyclic(w *bufio.Writer, v reflect.Value, visited map[uintptr]bool)
|
|||
defer mapHasherPool.Put(mh)
|
||||
mh.Reset()
|
||||
iter := v.MapRange()
|
||||
k := reflect.New(v.Type().Key()).Elem()
|
||||
e := reflect.New(v.Type().Elem()).Elem()
|
||||
for iter.Next() {
|
||||
key := iterKey(iter, k)
|
||||
val := iterVal(iter, e)
|
||||
mh.startEntry()
|
||||
if !print(mh.bw, iter.Key(), visited) {
|
||||
if !print(mh.bw, key, visited) {
|
||||
return false
|
||||
}
|
||||
if !print(mh.bw, iter.Value(), visited) {
|
||||
if !print(mh.bw, val, visited) {
|
||||
return false
|
||||
}
|
||||
mh.endEntry()
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !tailscale_go
|
||||
|
||||
package deephash
|
||||
|
||||
import "reflect"
|
||||
|
||||
func iterKey(iter *reflect.MapIter, scratch reflect.Value) reflect.Value {
|
||||
return iter.Key()
|
||||
}
|
||||
|
||||
func iterVal(iter *reflect.MapIter, scratch reflect.Value) reflect.Value {
|
||||
return iter.Value()
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build tailscale_go
|
||||
|
||||
package deephash
|
||||
|
||||
import "reflect"
|
||||
|
||||
func iterKey(iter *reflect.MapIter, scratch reflect.Value) reflect.Value {
|
||||
iter.SetKey(scratch)
|
||||
return scratch
|
||||
}
|
||||
|
||||
func iterVal(iter *reflect.MapIter, scratch reflect.Value) reflect.Value {
|
||||
iter.SetValue(scratch)
|
||||
return scratch
|
||||
}
|
Loading…
Reference in New Issue