mirror of
https://github.com/golang/go
synced 2024-11-26 03:07:57 -07:00
fmt: speed up 10-20%
The check for Stringer etc. can only fire if the test is not a builtin, so avoid the expensive check if we know there's no chance. Also put in a fast path for pad, which saves a more modest amount. benchmark old ns/op new ns/op delta BenchmarkSprintfEmpty 148 152 +2.70% BenchmarkSprintfString 585 497 -15.04% BenchmarkSprintfInt 441 396 -10.20% BenchmarkSprintfIntInt 718 603 -16.02% BenchmarkSprintfPrefixedInt 676 621 -8.14% BenchmarkSprintfFloat 1003 953 -4.99% BenchmarkManyArgs 2945 2312 -21.49% BenchmarkScanInts 1704152 1734441 +1.78% BenchmarkScanRecursiveInt 1837397 1828920 -0.46% R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/6245068
This commit is contained in:
parent
d61707f490
commit
53bc19442d
@ -527,6 +527,14 @@ func BenchmarkSprintfFloat(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkManyArgs(b *testing.B) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
buf.Reset()
|
||||||
|
Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var mallocBuf bytes.Buffer
|
var mallocBuf bytes.Buffer
|
||||||
|
|
||||||
var mallocTest = []struct {
|
var mallocTest = []struct {
|
||||||
|
@ -110,11 +110,11 @@ func (f *fmt) writePadding(n int, padding []byte) {
|
|||||||
// Append b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus)
|
// Append b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus)
|
||||||
// clear flags afterwards.
|
// clear flags afterwards.
|
||||||
func (f *fmt) pad(b []byte) {
|
func (f *fmt) pad(b []byte) {
|
||||||
var padding []byte
|
if !f.widPresent || f.wid == 0 {
|
||||||
var left, right int
|
f.buf.Write(b)
|
||||||
if f.widPresent && f.wid != 0 {
|
return
|
||||||
padding, left, right = f.computePadding(len(b))
|
|
||||||
}
|
}
|
||||||
|
padding, left, right := f.computePadding(len(b))
|
||||||
if left > 0 {
|
if left > 0 {
|
||||||
f.writePadding(left, padding)
|
f.writePadding(left, padding)
|
||||||
}
|
}
|
||||||
@ -127,11 +127,11 @@ func (f *fmt) pad(b []byte) {
|
|||||||
// append s to buf, padded on left (w > 0) or right (w < 0 or f.minus).
|
// append s to buf, padded on left (w > 0) or right (w < 0 or f.minus).
|
||||||
// clear flags afterwards.
|
// clear flags afterwards.
|
||||||
func (f *fmt) padString(s string) {
|
func (f *fmt) padString(s string) {
|
||||||
var padding []byte
|
if !f.widPresent || f.wid == 0 {
|
||||||
var left, right int
|
f.buf.WriteString(s)
|
||||||
if f.widPresent && f.wid != 0 {
|
return
|
||||||
padding, left, right = f.computePadding(utf8.RuneCountInString(s))
|
|
||||||
}
|
}
|
||||||
|
padding, left, right := f.computePadding(utf8.RuneCountInString(s))
|
||||||
if left > 0 {
|
if left > 0 {
|
||||||
f.writePadding(left, padding)
|
f.writePadding(left, padding)
|
||||||
}
|
}
|
||||||
|
@ -734,10 +734,6 @@ func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if wasString, handled := p.handleMethods(verb, plus, goSyntax, depth); handled {
|
|
||||||
return wasString
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some types can be done without reflection.
|
// Some types can be done without reflection.
|
||||||
switch f := field.(type) {
|
switch f := field.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
@ -779,6 +775,10 @@ func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth
|
|||||||
p.fmtBytes(f, verb, goSyntax, depth)
|
p.fmtBytes(f, verb, goSyntax, depth)
|
||||||
wasString = verb == 's'
|
wasString = verb == 's'
|
||||||
default:
|
default:
|
||||||
|
// If the type is not simple, it might have methods.
|
||||||
|
if wasString, handled := p.handleMethods(verb, plus, goSyntax, depth); handled {
|
||||||
|
return wasString
|
||||||
|
}
|
||||||
// Need to use reflection
|
// Need to use reflection
|
||||||
return p.printReflectValue(reflect.ValueOf(field), verb, plus, goSyntax, depth)
|
return p.printReflectValue(reflect.ValueOf(field), verb, plus, goSyntax, depth)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user