From e577303dc7807215b85f05cc2dbdb1e12fc9f4f7 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 7 Aug 2020 16:25:59 -0700 Subject: [PATCH] derp: make writeUint32 and readUint32 not allocate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The allocations are small, but they're easy enough to avoid. And it removes some clutter from the pprof output. name old time/op new time/op delta SendRecv/msgsize=10-8 10.1µs ± 9% 9.7µs ± 7% -3.45% (p=0.035 n=14+14) SendRecv/msgsize=100-8 8.12µs ± 7% 7.38µs ± 9% -9.02% (p=0.000 n=15+15) SendRecv/msgsize=1000-8 9.51µs ±25% 8.76µs ±22% ~ (p=0.202 n=15+15) SendRecv/msgsize=10000-8 21.1µs ±25% 19.9µs ±14% ~ (p=0.270 n=15+14) WriteUint32-8 25.1ns ± 4% 21.3ns ±12% -15.01% (p=0.000 n=14+14) ReadUint32-8 35.4ns ± 4% 21.9ns ± 4% -38.06% (p=0.000 n=15+15) name old alloc/op new alloc/op delta SendRecv/msgsize=10-8 182B ± 2% 169B ± 1% -7.22% (p=0.000 n=15+13) SendRecv/msgsize=100-8 282B ± 1% 265B ± 1% -5.85% (p=0.000 n=15+15) SendRecv/msgsize=1000-8 1.19kB ± 1% 1.18kB ± 0% -1.26% (p=0.000 n=14+15) SendRecv/msgsize=10000-8 19.3kB ± 4% 18.7kB ± 4% -3.44% (p=0.006 n=12+12) WriteUint32-8 4.00B ± 0% 0.00B -100.00% (p=0.000 n=15+15) ReadUint32-8 4.00B ± 0% 0.00B -100.00% (p=0.000 n=15+15) name old allocs/op new allocs/op delta SendRecv/msgsize=10-8 8.00 ± 0% 4.00 ± 0% -50.00% (p=0.000 n=15+15) SendRecv/msgsize=100-8 8.00 ± 0% 4.00 ± 0% -50.00% (p=0.000 n=15+15) SendRecv/msgsize=1000-8 8.00 ± 0% 4.00 ± 0% -50.00% (p=0.000 n=15+15) SendRecv/msgsize=10000-8 8.47 ±17% 5.00 ± 0% -40.94% (p=0.000 n=15+14) WriteUint32-8 1.00 ± 0% 0.00 -100.00% (p=0.000 n=15+15) ReadUint32-8 1.00 ± 0% 0.00 -100.00% (p=0.000 n=15+15) Signed-off-by: Josh Bleecher Snyder --- derp/derp.go | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/derp/derp.go b/derp/derp.go index a6799ce86..9e537ba53 100644 --- a/derp/derp.go +++ b/derp/derp.go @@ -108,16 +108,31 @@ func writeUint32(bw *bufio.Writer, v uint32) error { var b [4]byte bin.PutUint32(b[:], v) - _, err := bw.Write(b[:]) - return err + // Writing a byte at a time is a bit silly, + // but it causes b not to escape, + // which more than pays for the silliness. + for _, c := range &b { + err := bw.WriteByte(c) + if err != nil { + return err + } + } + return nil } func readUint32(br *bufio.Reader) (uint32, error) { - b := make([]byte, 4) - if _, err := io.ReadFull(br, b); err != nil { - return 0, err + var b [4]byte + // Reading a byte at a time is a bit silly, + // but it causes b not to escape, + // which more than pays for the silliness. + for i := range &b { + c, err := br.ReadByte() + if err != nil { + return 0, err + } + b[i] = c } - return bin.Uint32(b), nil + return bin.Uint32(b[:]), nil } func readFrameTypeHeader(br *bufio.Reader, wantType frameType) (frameLen uint32, err error) {