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>
pull/1980/head
Josh Bleecher Snyder 4 years ago committed by Josh Bleecher Snyder
parent 09afb8e35b
commit b371588ce6

@ -51,6 +51,13 @@ var (
tailcfgDiscoKeyType = reflect.TypeOf(tailcfg.DiscoKey{}) 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. // print hashes v into w.
// It reports whether it was able to do so without hitting a cycle. // 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) { 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() { if v.CanInterface() {
switch v.Type() { switch v.Type() {
case netaddrIPType: case netaddrIPType:
var b []byte b := bufPool.Get().(*[]byte)
var err error defer bufPool.Put(b)
*b = (*b)[:0]
if v.CanAddr() { if v.CanAddr() {
x := v.Addr().Interface().(*netaddr.IP) x := v.Addr().Interface().(*netaddr.IP)
b, err = x.MarshalText() *b = x.AppendTo(*b)
} else { } else {
x := v.Interface().(netaddr.IP) x := v.Interface().(netaddr.IP)
b, err = x.MarshalText() *b = x.AppendTo(*b)
}
if err == nil {
w.Write(b)
return true
} }
w.Write(*b)
return true
case netaddrIPPrefix: case netaddrIPPrefix:
var b []byte b := bufPool.Get().(*[]byte)
var err error defer bufPool.Put(b)
*b = (*b)[:0]
if v.CanAddr() { if v.CanAddr() {
x := v.Addr().Interface().(*netaddr.IPPrefix) x := v.Addr().Interface().(*netaddr.IPPrefix)
b, err = x.MarshalText() *b = x.AppendTo(*b)
} else { } else {
x := v.Interface().(netaddr.IPPrefix) x := v.Interface().(netaddr.IPPrefix)
b, err = x.MarshalText() *b = x.AppendTo(*b)
}
if err == nil {
w.Write(b)
return true
} }
w.Write(*b)
return true
case netaddrIPPort: case netaddrIPPort:
var b []byte b := bufPool.Get().(*[]byte)
var err error defer bufPool.Put(b)
*b = (*b)[:0]
if v.CanAddr() { if v.CanAddr() {
x := v.Addr().Interface().(*netaddr.IPPort) x := v.Addr().Interface().(*netaddr.IPPort)
b, err = x.MarshalText() *b = x.AppendTo(*b)
} else { } else {
x := v.Interface().(netaddr.IPPort) x := v.Interface().(netaddr.IPPort)
b, err = x.MarshalText() *b = x.AppendTo(*b)
}
if err == nil {
w.Write(b)
return true
} }
w.Write(*b)
return true
case wgkeyKeyType: case wgkeyKeyType:
if v.CanAddr() { if v.CanAddr() {
x := v.Addr().Interface().(*wgkey.Key) x := v.Addr().Interface().(*wgkey.Key)

Loading…
Cancel
Save