package node import ( "bytes" "encoding/json" "sync" ) // buffer := getBuffer(); defer putBuffer(buffer); encoder := json.NewEncoder(buffer) var bufferPool = sync.Pool{ New: func() interface{} { return bytes.NewBuffer(make([]byte, 0, 1024)) }, } // buffer := getBuffer() // defer putBuffer(buffer) func getBuffer() *bytes.Buffer { buffer := bufferPool.Get().(*bytes.Buffer) buffer.Reset() return buffer } // putBuffer(buffer) // always called via defer after getBuffer() func putBuffer(buffer *bytes.Buffer) { // Don't pool buffers that grew too large (>64KB) if buffer.Cap() <= 65536 { bufferPool.Put(buffer) } } // var msg Message // if err := UnmarshalJSON(data, &msg); err != nil { return nil, err } func UnmarshalJSON(data []byte, target interface{}) error { return json.Unmarshal(data, target) } // data, err := MarshalJSON(msg) // if err != nil { return nil, err } func MarshalJSON(value interface{}) ([]byte, error) { buffer := getBuffer() defer putBuffer(buffer) encoder := json.NewEncoder(buffer) // Don't escape HTML characters (matches json.Marshal behavior for these use cases) encoder.SetEscapeHTML(false) if err := encoder.Encode(value); err != nil { return nil, err } // json.Encoder.Encode adds a newline; remove it to match json.Marshal data := buffer.Bytes() if len(data) > 0 && data[len(data)-1] == '\n' { data = data[:len(data)-1] } result := make([]byte, len(data)) copy(result, data) return result, nil }