internal/deepprint: special-case some common types

These show up a lot in our data structures.

name    old time/op    new time/op    delta
Hash-8    11.5µs ± 1%     7.8µs ± 1%  -32.17%  (p=0.000 n=10+10)

name    old alloc/op   new alloc/op   delta
Hash-8    1.98kB ± 0%    1.67kB ± 0%  -15.73%  (p=0.000 n=10+10)

name    old allocs/op  new allocs/op  delta
Hash-8      82.0 ± 0%      53.0 ± 0%  -35.37%  (p=0.000 n=10+10)

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
pull/1908/head
Josh Bleecher Snyder 4 years ago committed by Josh Bleecher Snyder
parent 752f8c0f2f
commit d4f805339e

@ -16,6 +16,10 @@ import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"reflect" "reflect"
"inet.af/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/wgkey"
) )
func Hash(v ...interface{}) string { func Hash(v ...interface{}) string {
@ -41,10 +45,81 @@ func Print(w *bufio.Writer, v ...interface{}) {
print(w, reflect.ValueOf(v), make(map[uintptr]bool)) print(w, reflect.ValueOf(v), make(map[uintptr]bool))
} }
var (
netaddrIPType = reflect.TypeOf(netaddr.IP{})
netaddrIPPrefix = reflect.TypeOf(netaddr.IPPrefix{})
wgkeyKeyType = reflect.TypeOf(wgkey.Key{})
wgkeyPrivateType = reflect.TypeOf(wgkey.Private{})
tailcfgDiscoKeyType = reflect.TypeOf(tailcfg.DiscoKey{})
)
func print(w *bufio.Writer, v reflect.Value, visited map[uintptr]bool) { func print(w *bufio.Writer, v reflect.Value, visited map[uintptr]bool) {
if !v.IsValid() { if !v.IsValid() {
return return
} }
// Special case some common types.
if v.CanInterface() {
switch v.Type() {
case netaddrIPType:
var b []byte
var err error
if v.CanAddr() {
x := v.Addr().Interface().(*netaddr.IP)
b, err = x.MarshalText()
} else {
x := v.Interface().(netaddr.IP)
b, err = x.MarshalText()
}
if err == nil {
w.Write(b)
return
}
case netaddrIPPrefix:
var b []byte
var err error
if v.CanAddr() {
x := v.Addr().Interface().(*netaddr.IPPrefix)
b, err = x.MarshalText()
} else {
x := v.Interface().(netaddr.IPPrefix)
b, err = x.MarshalText()
}
if err == nil {
w.Write(b)
return
}
case wgkeyKeyType:
if v.CanAddr() {
x := v.Addr().Interface().(*wgkey.Key)
w.Write(x[:])
} else {
x := v.Interface().(wgkey.Key)
w.Write(x[:])
}
return
case wgkeyPrivateType:
if v.CanAddr() {
x := v.Addr().Interface().(*wgkey.Private)
w.Write(x[:])
} else {
x := v.Interface().(wgkey.Private)
w.Write(x[:])
}
return
case tailcfgDiscoKeyType:
if v.CanAddr() {
x := v.Addr().Interface().(*tailcfg.DiscoKey)
w.Write(x[:])
} else {
x := v.Interface().(tailcfg.DiscoKey)
w.Write(x[:])
}
return
}
}
// Generic handling.
switch v.Kind() { switch v.Kind() {
default: default:
panic(fmt.Sprintf("unhandled kind %v for type %v", v.Kind(), v.Type())) panic(fmt.Sprintf("unhandled kind %v for type %v", v.Kind(), v.Type()))

Loading…
Cancel
Save