From 1e8e785321d25e103817e134a4e716ac715069ce Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Wed, 7 Feb 2018 17:30:57 +0000 Subject: [PATCH] Remove allocs from WriteFloat32/WriteFloat64 The use of strconv.FormatFloat causes a string allocation, by setting aside a reusable buffer and using strconv.AppendFloat this can be avoided. Before: BenchmarkRespond-4 300 5392189 ns/op 618936 B/op 20010 allocs/op After: BenchmarkRespond-4 300 4713746 ns/op 139744 B/op 10 allocs/op This benchmark is using a custom encoder that calls WriteFloat64 20k times, which is the bulk of the work. --- feature_stream.go | 2 ++ feature_stream_float.go | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/feature_stream.go b/feature_stream.go index 97355eb5..db78ec6f 100644 --- a/feature_stream.go +++ b/feature_stream.go @@ -14,6 +14,7 @@ type Stream struct { Error error indention int Attachment interface{} // open for customized encoder + floatBuf []byte } // NewStream create new stream instance. @@ -28,6 +29,7 @@ func NewStream(cfg API, out io.Writer, bufSize int) *Stream { n: 0, Error: nil, indention: 0, + floatBuf: make([]byte, 0, 32), } } diff --git a/feature_stream_float.go b/feature_stream_float.go index 9a404e11..2838713f 100644 --- a/feature_stream_float.go +++ b/feature_stream_float.go @@ -21,7 +21,9 @@ func (stream *Stream) WriteFloat32(val float32) { fmt = 'e' } } - stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 32)) + stream.floatBuf = strconv.AppendFloat(stream.floatBuf, float64(val), fmt, -1, 32) + stream.Write(stream.floatBuf) + stream.floatBuf = stream.floatBuf[:0] } // WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster @@ -63,7 +65,9 @@ func (stream *Stream) WriteFloat64(val float64) { fmt = 'e' } } - stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 64)) + stream.floatBuf = strconv.AppendFloat(stream.floatBuf, float64(val), fmt, -1, 64) + stream.Write(stream.floatBuf) + stream.floatBuf = stream.floatBuf[:0] } // WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster