bytepool: store *[]byte

This avoids allocations for the slice metadata.

For more details, see:
https://staticcheck.io/docs/checks#SA6002
This commit is contained in:
Jimmy Zelinskie 2022-01-15 13:58:06 -05:00
parent 65ce7c7c6b
commit b81a310eea
2 changed files with 14 additions and 11 deletions

View file

@ -11,24 +11,27 @@ type BytePool struct {
func New(length int) *BytePool { func New(length int) *BytePool {
var bp BytePool var bp BytePool
bp.Pool.New = func() interface{} { bp.Pool.New = func() interface{} {
return make([]byte, length) b := make([]byte, length)
return &b
} }
return &bp return &bp
} }
// Get returns a byte slice from the pool. // Get returns a byte slice from the pool.
func (bp *BytePool) Get() []byte { func (bp *BytePool) Get() *[]byte {
return bp.Pool.Get().([]byte) return bp.Pool.Get().(*[]byte)
} }
// Put returns a byte slice to the pool. // Put returns a byte slice to the pool.
func (bp *BytePool) Put(b []byte) { func (bp *BytePool) Put(b *[]byte) {
b = b[:cap(b)] *b = (*b)[:cap(*b)]
// Zero out the bytes. // Zero out the bytes.
// Apparently this specific expression is optimized by the compiler, see // This specific expression is optimized by the compiler:
// github.com/golang/go/issues/5373. // https://github.com/golang/go/issues/5373.
for i := range b { for i := range *b {
b[i] = 0 (*b)[i] = 0
} }
bp.Pool.Put(b) bp.Pool.Put(b)
} }

View file

@ -185,7 +185,7 @@ func (t *Frontend) serve() error {
// Read a UDP packet into a reusable buffer. // Read a UDP packet into a reusable buffer.
buffer := pool.Get() buffer := pool.Get()
n, addr, err := t.socket.ReadFromUDP(buffer) n, addr, err := t.socket.ReadFromUDP(*buffer)
if err != nil { if err != nil {
pool.Put(buffer) pool.Put(buffer)
if netErr, ok := err.(net.Error); ok && netErr.Temporary() { if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
@ -217,7 +217,7 @@ func (t *Frontend) serve() error {
} }
action, af, err := t.handleRequest( action, af, err := t.handleRequest(
// Make sure the IP is copied, not referenced. // Make sure the IP is copied, not referenced.
Request{buffer[:n], append([]byte{}, addr.IP...)}, Request{(*buffer)[:n], append([]byte{}, addr.IP...)},
ResponseWriter{t.socket, addr}, ResponseWriter{t.socket, addr},
) )
if t.EnableRequestTiming { if t.EnableRequestTiming {