From ceb568202b411ffd9a24761b56445181d65fa735 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 7 May 2021 17:01:44 -0700 Subject: [PATCH] tailcfg: optimize keyMarshalText MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function accounted for ~1% of all allocs by tailscaled. It is trivial to improve, so may as well. name old time/op new time/op delta KeyMarshalText-8 197ns ± 0% 47ns ± 0% -76.12% (p=0.016 n=4+5) name old alloc/op new alloc/op delta KeyMarshalText-8 200B ± 0% 80B ± 0% -60.00% (p=0.008 n=5+5) name old allocs/op new allocs/op delta KeyMarshalText-8 5.00 ± 0% 1.00 ± 0% -80.00% (p=0.008 n=5+5) Signed-off-by: Josh Bleecher Snyder --- tailcfg/tailcfg.go | 9 +++++---- tailcfg/tailcfg_test.go | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index 483a67867..f1a9e3749 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -7,7 +7,7 @@ package tailcfg //go:generate go run tailscale.com/cmd/cloner --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse --clonefunc=true --output=tailcfg_clone.go import ( - "bytes" + "encoding/hex" "errors" "fmt" "reflect" @@ -1027,9 +1027,10 @@ func (k MachineKey) HexString() string { return fmt.Sprintf("%x", func (k *MachineKey) UnmarshalText(text []byte) error { return keyUnmarshalText(k[:], "mkey:", text) } func keyMarshalText(prefix string, k [32]byte) []byte { - buf := bytes.NewBuffer(make([]byte, 0, len(prefix)+64)) - fmt.Fprintf(buf, "%s%x", prefix, k[:]) - return buf.Bytes() + buf := make([]byte, len(prefix)+64) + copy(buf, prefix) + hex.Encode(buf[len(prefix):], k[:]) + return buf } func keyUnmarshalText(dst []byte, prefix string, text []byte) error { diff --git a/tailcfg/tailcfg_test.go b/tailcfg/tailcfg_test.go index 410e532e5..7632f3ccb 100644 --- a/tailcfg/tailcfg_test.go +++ b/tailcfg/tailcfg_test.go @@ -518,3 +518,13 @@ func TestEndpointTypeMarshal(t *testing.T) { t.Errorf("got %s; want %s", got, want) } } + +var sinkBytes []byte + +func BenchmarkKeyMarshalText(b *testing.B) { + b.ReportAllocs() + var k [32]byte + for i := 0; i < b.N; i++ { + sinkBytes = keyMarshalText("prefix", k) + } +}