internal/deephash: use netaddr AppendTo methods

Slightly slower, but lots less garbage.
We will recover the speed lost in a follow-up commit.

name    old time/op    new time/op    delta
Hash-8    13.5µs ± 1%    14.3µs ± 0%   +5.84%  (p=0.000 n=10+9)

name    old alloc/op   new alloc/op   delta
Hash-8    1.46kB ± 0%    0.87kB ± 0%  -40.10%  (p=0.000 n=7+10)

name    old allocs/op  new allocs/op  delta
Hash-8      43.0 ± 0%      18.0 ± 0%  -58.14%  (p=0.000 n=10+10)

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
Josh Bleecher Snyder 2021-05-18 12:44:31 -07:00 committed by Josh Bleecher Snyder
parent 09afb8e35b
commit b371588ce6
1 changed files with 28 additions and 24 deletions

View File

@ -51,6 +51,13 @@ var (
tailcfgDiscoKeyType = reflect.TypeOf(tailcfg.DiscoKey{})
)
// bufPool contains *[]byte, used when printing netaddr types.
var bufPool = sync.Pool{
New: func() interface{} {
return new([]byte)
},
}
// print hashes v into w.
// It reports whether it was able to do so without hitting a cycle.
func print(w *bufio.Writer, v reflect.Value, visited map[uintptr]bool) (acyclic bool) {
@ -62,47 +69,44 @@ func print(w *bufio.Writer, v reflect.Value, visited map[uintptr]bool) (acyclic
if v.CanInterface() {
switch v.Type() {
case netaddrIPType:
var b []byte
var err error
b := bufPool.Get().(*[]byte)
defer bufPool.Put(b)
*b = (*b)[:0]
if v.CanAddr() {
x := v.Addr().Interface().(*netaddr.IP)
b, err = x.MarshalText()
*b = x.AppendTo(*b)
} else {
x := v.Interface().(netaddr.IP)
b, err = x.MarshalText()
}
if err == nil {
w.Write(b)
return true
*b = x.AppendTo(*b)
}
w.Write(*b)
return true
case netaddrIPPrefix:
var b []byte
var err error
b := bufPool.Get().(*[]byte)
defer bufPool.Put(b)
*b = (*b)[:0]
if v.CanAddr() {
x := v.Addr().Interface().(*netaddr.IPPrefix)
b, err = x.MarshalText()
*b = x.AppendTo(*b)
} else {
x := v.Interface().(netaddr.IPPrefix)
b, err = x.MarshalText()
}
if err == nil {
w.Write(b)
return true
*b = x.AppendTo(*b)
}
w.Write(*b)
return true
case netaddrIPPort:
var b []byte
var err error
b := bufPool.Get().(*[]byte)
defer bufPool.Put(b)
*b = (*b)[:0]
if v.CanAddr() {
x := v.Addr().Interface().(*netaddr.IPPort)
b, err = x.MarshalText()
*b = x.AppendTo(*b)
} else {
x := v.Interface().(netaddr.IPPort)
b, err = x.MarshalText()
}
if err == nil {
w.Write(b)
return true
*b = x.AppendTo(*b)
}
w.Write(*b)
return true
case wgkeyKeyType:
if v.CanAddr() {
x := v.Addr().Interface().(*wgkey.Key)