瀏覽代碼

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.
Brian Brazil 7 年之前
父節點
當前提交
1e8e785321
共有 2 個文件被更改,包括 8 次插入2 次删除
  1. 2 0
      feature_stream.go
  2. 6 2
      feature_stream_float.go

+ 2 - 0
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),
 	}
 }
 

+ 6 - 2
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