From 5c55014b328dd466271f7cce8bfa111f42e081b2 Mon Sep 17 00:00:00 2001 From: Alexander Menshchikov Date: Mon, 9 Oct 2023 12:07:36 +0300 Subject: [PATCH] Use sync.Pool and bytes.Buffer for Logger.With perf improvement --- log.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/log.go b/log.go index 834c7e60..3a42816c 100644 --- a/log.go +++ b/log.go @@ -114,6 +114,7 @@ package zerolog import ( + "bytes" "context" "errors" "fmt" @@ -122,8 +123,15 @@ import ( "os" "strconv" "strings" + "sync" ) +var contextBufPool = &sync.Pool{ + New: func() interface{} { + return bytes.NewBuffer(make([]byte, 0, 500)) + }, +} + // Level defines log levels. type Level int8 @@ -278,15 +286,18 @@ func (l Logger) Output(w io.Writer) Logger { // With creates a child logger with the field added to its context. func (l Logger) With() Context { - context := l.context - l.context = make([]byte, 0, 500) - if context != nil { - l.context = append(l.context, context...) + buf := contextBufPool.Get().(*bytes.Buffer) + ctx := l.context + if ctx != nil { + buf.Write(ctx) } else { // This is needed for AppendKey to not check len of input // thus making it inlinable - l.context = enc.AppendBeginMarker(l.context) + buf.Write(enc.AppendBeginMarker(buf.Bytes())) } + l.context = buf.Bytes() + buf.Reset() + contextBufPool.Put(buf) return Context{l} } @@ -299,7 +310,9 @@ func (l *Logger) UpdateContext(update func(c Context) Context) { return } if cap(l.context) == 0 { - l.context = make([]byte, 0, 500) + buf := contextBufPool.Get().(*bytes.Buffer) + l.context = buf.Bytes() + contextBufPool.Put(buf) } if len(l.context) == 0 { l.context = enc.AppendBeginMarker(l.context)