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

View file

@ -185,7 +185,7 @@ func (t *Frontend) serve() error {
// Read a UDP packet into a reusable buffer.
buffer := pool.Get()
n, addr, err := t.socket.ReadFromUDP(buffer)
n, addr, err := t.socket.ReadFromUDP(*buffer)
if err != nil {
pool.Put(buffer)
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
@ -217,7 +217,7 @@ func (t *Frontend) serve() error {
}
action, af, err := t.handleRequest(
// 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},
)
if t.EnableRequestTiming {