mirror of
https://github.com/golang/go
synced 2024-11-18 08:44:43 -07:00
all: remove unnecessary allocations from w.WriteString(fmt.Sprint*(...)) by fmt.Fprint*(w, ...)
Noticed in a manual audit from a customer codebase that the pattern w.WriteString(fmt.Sprint*(args...)) was less efficient and in most cases we can just invoke: fmt.Fprint*(w, args...) and from the simple benchmarks we can see quick wins in all dimensions: $ benchstat before.txt after.txt name old time/op new time/op delta DetailString-8 5.48µs ±23% 4.40µs ±11% -19.79% (p=0.000 n=20+17) name old alloc/op new alloc/op delta DetailString-8 2.63kB ± 0% 2.11kB ± 0% -19.76% (p=0.000 n=20+20) name old allocs/op new allocs/op delta DetailString-8 63.0 ± 0% 50.0 ± 0% -20.63% (p=0.000 n=20+20) Change-Id: I47a2827cd34d6b92644900b1bd5f4c0a3287bdb1 Reviewed-on: https://go-review.googlesource.com/c/go/+/429861 Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: hopehook <hopehook@golangcn.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
This commit is contained in:
parent
a7e9a379e9
commit
4baa486983
@ -339,7 +339,7 @@ func (t *T) String() string {
|
|||||||
}
|
}
|
||||||
b.WriteString(strconv.FormatInt(int64(k), 10))
|
b.WriteString(strconv.FormatInt(int64(k), 10))
|
||||||
b.WriteString(":")
|
b.WriteString(":")
|
||||||
b.WriteString(fmt.Sprint(v))
|
fmt.Fprint(&b, v)
|
||||||
}
|
}
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
@ -7271,7 +7271,7 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
|
|||||||
}
|
}
|
||||||
buf.WriteString("</dt>")
|
buf.WriteString("</dt>")
|
||||||
buf.WriteString("<dd class=\"ssa-prog\">")
|
buf.WriteString("<dd class=\"ssa-prog\">")
|
||||||
buf.WriteString(fmt.Sprintf("%.5d <span class=\"l%v line-number\">(%s)</span> %s", p.Pc, p.InnermostLineNumber(), p.InnermostLineNumberHTML(), html.EscapeString(p.InstructionString())))
|
fmt.Fprintf(&buf, "%.5d <span class=\"l%v line-number\">(%s)</span> %s", p.Pc, p.InnermostLineNumber(), p.InnermostLineNumberHTML(), html.EscapeString(p.InstructionString()))
|
||||||
buf.WriteString("</dd>")
|
buf.WriteString("</dd>")
|
||||||
}
|
}
|
||||||
buf.WriteString("</dl>")
|
buf.WriteString("</dl>")
|
||||||
|
@ -88,10 +88,10 @@ func TestEmbeddedTokens(t *testing.T) {
|
|||||||
// make source
|
// make source
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
for i, s := range sampleTokens {
|
for i, s := range sampleTokens {
|
||||||
buf.WriteString("\t\t\t\t"[:i&3]) // leading indentation
|
buf.WriteString("\t\t\t\t"[:i&3]) // leading indentation
|
||||||
buf.WriteString(s.src) // token
|
buf.WriteString(s.src) // token
|
||||||
buf.WriteString(" "[:i&7]) // trailing spaces
|
buf.WriteString(" "[:i&7]) // trailing spaces
|
||||||
buf.WriteString(fmt.Sprintf("/*line foo:%d */ // bar\n", i)) // comments + newline (don't crash w/o directive handler)
|
fmt.Fprintf(&buf, "/*line foo:%d */ // bar\n", i) // comments + newline (don't crash w/o directive handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// scan source
|
// scan source
|
||||||
|
@ -577,7 +577,7 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type
|
|||||||
} else {
|
} else {
|
||||||
b.WriteString("tp")
|
b.WriteString("tp")
|
||||||
// Print out the pointer value for now to disambiguate type params
|
// Print out the pointer value for now to disambiguate type params
|
||||||
b.WriteString(fmt.Sprintf("%p", t))
|
fmt.Fprintf(b, "%p", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
case TUNION:
|
case TUNION:
|
||||||
|
@ -33,7 +33,7 @@ func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
|
|||||||
|
|
||||||
switch x := x.(type) {
|
switch x := x.(type) {
|
||||||
default:
|
default:
|
||||||
buf.WriteString(fmt.Sprintf("(ast: %T)", x)) // nil, ast.BadExpr, ast.KeyValueExpr
|
fmt.Fprintf(buf, "(ast: %T)", x) // nil, ast.BadExpr, ast.KeyValueExpr
|
||||||
|
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
buf.WriteString(x.Name)
|
buf.WriteString(x.Name)
|
||||||
|
@ -147,7 +147,7 @@ func sprint(data any) string {
|
|||||||
}
|
}
|
||||||
b.WriteString(sprintKey(key))
|
b.WriteString(sprintKey(key))
|
||||||
b.WriteRune(':')
|
b.WriteRune(':')
|
||||||
b.WriteString(fmt.Sprint(om.Value[i]))
|
fmt.Fprint(b, om.Value[i])
|
||||||
}
|
}
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ func TestUserTaskRegion(t *testing.T) {
|
|||||||
pretty := func(data []testData) string {
|
pretty := func(data []testData) string {
|
||||||
var s strings.Builder
|
var s strings.Builder
|
||||||
for _, d := range data {
|
for _, d := range data {
|
||||||
s.WriteString(fmt.Sprintf("\t%+v\n", d))
|
fmt.Fprintf(&s, "\t%+v\n", d)
|
||||||
}
|
}
|
||||||
return s.String()
|
return s.String()
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ func genasmArm() {
|
|||||||
TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
|
TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
|
||||||
`)
|
`)
|
||||||
for i := 0; i < maxCallback; i++ {
|
for i := 0; i < maxCallback; i++ {
|
||||||
buf.WriteString(fmt.Sprintf("\tMOVW\t$%d, R12\n", i))
|
fmt.Fprintf(&buf, "\tMOVW\t$%d, R12\n", i)
|
||||||
buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
|
buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ func genasmArm64() {
|
|||||||
TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
|
TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
|
||||||
`)
|
`)
|
||||||
for i := 0; i < maxCallback; i++ {
|
for i := 0; i < maxCallback; i++ {
|
||||||
buf.WriteString(fmt.Sprintf("\tMOVD\t$%d, R12\n", i))
|
fmt.Fprintf(&buf, "\tMOVD\t$%d, R12\n", i)
|
||||||
buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
|
buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,12 +104,12 @@ TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
|
|||||||
func gengo() {
|
func gengo() {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
buf.WriteString(fmt.Sprintf(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
|
fmt.Fprintf(&buf, `// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
|
||||||
|
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
const cb_max = %d // maximum number of windows callbacks allowed
|
const cb_max = %d // maximum number of windows callbacks allowed
|
||||||
`, maxCallback))
|
`, maxCallback)
|
||||||
err := os.WriteFile("zcallback_windows.go", buf.Bytes(), 0666)
|
err := os.WriteFile("zcallback_windows.go", buf.Bytes(), 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
|
fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user