Reuse Buffers with sync.Pool
Cut per-request allocations by borrowing bytes.Buffer from sync.Pool, copying the encoded JSON, and always returning the buffer.
Code
package main
import (
"bytes"
"encoding/json"
"fmt"
"sync"
)
var bufferPool = sync.Pool{
New: func() any { return new(bytes.Buffer) },
}
func EncodeJSON(value any) ([]byte, error) {
buffer := bufferPool.Get().(*bytes.Buffer)
buffer.Reset()
defer bufferPool.Put(buffer)
if err := json.NewEncoder(buffer).Encode(value); err != nil {
return nil, err
}
out := make([]byte, buffer.Len())
copy(out, buffer.Bytes())
return out, nil
}
func main() {
type payload struct {
ID int `json:"id"`
Name string `json:"name"`
}
encoded, err := EncodeJSON(payload{ID: 1, Name: "Ada"})
if err != nil {
panic(err)
}
fmt.Print(string(encoded))
fmt.Println(bytes.Equal(encoded, []byte("{\"id\":1,\"name\":\"Ada\"}\n")))
}
Report a problem with this exampleOpens a pre-filled issue on GitHub.