From 527a98e44003a3d0cfefb8b6dce3dfe88b2d3bc7 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 12 Nov 2015 14:09:03 +0000 Subject: [PATCH] crypto/tls, crypto/aes: remove allocations when Writing & Reading benchmark old ns/op new ns/op delta BenchmarkTLS-4 8571 7938 -7.39% benchmark old MB/s new MB/s speedup BenchmarkTLS-4 119.46 128.98 1.08x benchmark old allocs new allocs delta BenchmarkTLS-4 8 0 -100.00% benchmark old bytes new bytes delta BenchmarkTLS-4 128 0 -100.00% On: func BenchmarkTLS(b *testing.B) { b.ReportAllocs() b.SetBytes(1024) ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { io.Copy(ioutil.Discard, r.Body) })) defer ts.Close() buf := make([]byte, 1024) for i := range buf { buf[i] = byte(i) } c, err := tls.Dial("tcp", ts.Listener.Addr().String(), &tls.Config{ InsecureSkipVerify: true, }) if err != nil { b.Fatal(err) } defer c.Close() clen := int64(b.N) * 1024 if _, err := c.Write([]byte( "POST / HTTP/1.1\r\nHost: foo\r\nContent-Length: " + fmt.Sprint(clen) + "\r\n\r\n")); err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { if _, err := c.Write(buf); err != nil { b.Fatal(err) } } } Change-Id: I206e7e2118b97148f9751b740d8470895634d3f5 Reviewed-on: https://go-review.googlesource.com/16828 Reviewed-by: Adam Langley Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- conn.go | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/conn.go b/conn.go index e3dcf15..7638bbc 100644 --- a/conn.go +++ b/conn.go @@ -98,12 +98,13 @@ func (c *Conn) SetWriteDeadline(t time.Time) error { type halfConn struct { sync.Mutex - err error // first permanent error - version uint16 // protocol version - cipher interface{} // cipher algorithm - mac macFunction - seq [8]byte // 64-bit sequence number - bfree *block // list of free blocks + err error // first permanent error + version uint16 // protocol version + cipher interface{} // cipher algorithm + mac macFunction + seq [8]byte // 64-bit sequence number + bfree *block // list of free blocks + additionalData [13]byte // to avoid allocs; interface method args escape nextCipher interface{} // next encryption state nextMac macFunction // next MAC algorithm @@ -262,14 +263,13 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) nonce := payload[:8] payload = payload[8:] - var additionalData [13]byte - copy(additionalData[:], hc.seq[:]) - copy(additionalData[8:], b.data[:3]) + copy(hc.additionalData[:], hc.seq[:]) + copy(hc.additionalData[8:], b.data[:3]) n := len(payload) - c.Overhead() - additionalData[11] = byte(n >> 8) - additionalData[12] = byte(n) + hc.additionalData[11] = byte(n >> 8) + hc.additionalData[12] = byte(n) var err error - payload, err = c.Open(payload[:0], nonce, payload, additionalData[:]) + payload, err = c.Open(payload[:0], nonce, payload, hc.additionalData[:]) if err != nil { return false, 0, alertBadRecordMAC } @@ -378,13 +378,12 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) { payload := b.data[recordHeaderLen+explicitIVLen:] payload = payload[:payloadLen] - var additionalData [13]byte - copy(additionalData[:], hc.seq[:]) - copy(additionalData[8:], b.data[:3]) - additionalData[11] = byte(payloadLen >> 8) - additionalData[12] = byte(payloadLen) + copy(hc.additionalData[:], hc.seq[:]) + copy(hc.additionalData[8:], b.data[:3]) + hc.additionalData[11] = byte(payloadLen >> 8) + hc.additionalData[12] = byte(payloadLen) - c.Seal(payload[:0], nonce, payload, additionalData[:]) + c.Seal(payload[:0], nonce, payload, hc.additionalData[:]) case cbcMode: blockSize := c.BlockSize() if explicitIVLen > 0 {