mirror of
https://github.com/mikefarah/yq.git
synced 2026-09-06 18:24:57 +08:00
perf: use io.WriteString in writeString to avoid heap allocation (#2809)
writeString converted every string to []byte before calling io.Writer.Write, which Go escape analysis reports as escaping to the heap. io.WriteString uses the io.StringWriter fast path when available (the standard printer writer is a *bufio.Writer) and falls back to Write([]byte(txt)) otherwise. Fixes #2807 Co-authored-by: Pablo Garcia <pablito@MacBook-Neo-de-Pablo.local>
This commit is contained in:
+1
-1
@@ -50,7 +50,7 @@ func readStream(filename string) (io.Reader, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func writeString(writer io.Writer, txt string) error {
|
func writeString(writer io.Writer, txt string) error {
|
||||||
_, errorWriting := writer.Write([]byte(txt))
|
_, errorWriting := io.WriteString(writer, txt)
|
||||||
return errorWriting
|
return errorWriting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/v4/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
// plainWriter only implements io.Writer, so io.WriteString must fall back to Write.
|
||||||
|
type plainWriter struct {
|
||||||
|
buf bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *plainWriter) Write(p []byte) (int, error) {
|
||||||
|
return w.buf.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteStringToStringWriter(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
writer := bufio.NewWriter(&buf)
|
||||||
|
test.AssertResult(t, nil, writeString(writer, "hello world"))
|
||||||
|
test.AssertResult(t, nil, writer.Flush())
|
||||||
|
test.AssertResult(t, "hello world", buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteStringToPlainWriter(t *testing.T) {
|
||||||
|
writer := &plainWriter{}
|
||||||
|
test.AssertResult(t, nil, writeString(writer, "hello world"))
|
||||||
|
test.AssertResult(t, "hello world", writer.buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteStringDoesNotAllocate(t *testing.T) {
|
||||||
|
writer := bufio.NewWriter(io.Discard)
|
||||||
|
allocations := testing.AllocsPerRun(100, func() {
|
||||||
|
_ = writeString(writer, "hello world")
|
||||||
|
})
|
||||||
|
test.AssertResult(t, 0.0, allocations)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user