From b371588ce662829e642e9bb6b4e86b278242f73b Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Tue, 18 May 2021 12:44:31 -0700 Subject: [PATCH] internal/deephash: use netaddr AppendTo methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- internal/deephash/deephash.go | 52 +++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/internal/deephash/deephash.go b/internal/deephash/deephash.go index a15e0744e..fcbd59601 100644 --- a/internal/deephash/deephash.go +++ b/internal/deephash/deephash.go @@ -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)