]> Cypherpunks repositories - gostls13.git/commitdiff
fmt: speed up 10-20%
authorRob Pike <r@golang.org>
Tue, 29 May 2012 22:08:08 +0000 (15:08 -0700)
committerRob Pike <r@golang.org>
Tue, 29 May 2012 22:08:08 +0000 (15:08 -0700)
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

src/pkg/fmt/fmt_test.go
src/pkg/fmt/format.go
src/pkg/fmt/print.go

index de0342967cc36ae4e12c62d245526ad43105fc8f..a7632de8eeb3e94be2b51d1964080ad19c146d18 100644 (file)
@@ -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 mallocTest = []struct {
index caf900d5c3098caf3fcef0c5ef17c0f7a37b32d7..3c9cd0de696f2fef004039b2653ace2ad928b1b8 100644 (file)
@@ -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)
 // clear flags afterwards.
 func (f *fmt) pad(b []byte) {
-       var padding []byte
-       var left, right int
-       if f.widPresent && f.wid != 0 {
-               padding, left, right = f.computePadding(len(b))
+       if !f.widPresent || f.wid == 0 {
+               f.buf.Write(b)
+               return
        }
+       padding, left, right := f.computePadding(len(b))
        if left > 0 {
                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).
 // clear flags afterwards.
 func (f *fmt) padString(s string) {
-       var padding []byte
-       var left, right int
-       if f.widPresent && f.wid != 0 {
-               padding, left, right = f.computePadding(utf8.RuneCountInString(s))
+       if !f.widPresent || f.wid == 0 {
+               f.buf.WriteString(s)
+               return
        }
+       padding, left, right := f.computePadding(utf8.RuneCountInString(s))
        if left > 0 {
                f.writePadding(left, padding)
        }
index 13438243cdddc75fd52a9b7eed8f94bc7596ccc1..c730b18e9f0db7bf99a9d25740bd12b765dd3bae 100644 (file)
@@ -734,10 +734,6 @@ func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth
                return false
        }
 
-       if wasString, handled := p.handleMethods(verb, plus, goSyntax, depth); handled {
-               return wasString
-       }
-
        // Some types can be done without reflection.
        switch f := field.(type) {
        case bool:
@@ -779,6 +775,10 @@ func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth
                p.fmtBytes(f, verb, goSyntax, depth)
                wasString = verb == 's'
        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
                return p.printReflectValue(reflect.ValueOf(field), verb, plus, goSyntax, depth)
        }