Skip to content

Instantly share code, notes, and snippets.

@GeorgeErickson
Created September 15, 2016 21:16
Show Gist options
  • Save GeorgeErickson/2a2433892e0a0e4cb6b0542088db0973 to your computer and use it in GitHub Desktop.
Save GeorgeErickson/2a2433892e0a0e4cb6b0542088db0973 to your computer and use it in GitHub Desktop.
string bench
package main
import (
"bytes"
"fmt"
"math"
"strconv"
"strings"
"sync"
"testing"
)
var bufPool = sync.Pool{
New: func() interface{} { return new(bytes.Buffer) },
}
type benchFunc func(i int64) []byte
type benchFuncString func(i int64) string
func BenchmarkStringBuild(t *testing.B) {
exp := "9223372036854775807-9223372036854775807-9223372036854775807"
casesByte := map[string]benchFunc{
"strconv.AppendInt": func(i int64) []byte {
b := make([]byte, 0, 8*3+2)
b = strconv.AppendInt(b, i, 10)
b = append(b, '-')
b = strconv.AppendInt(b, i, 10)
b = append(b, '-')
b = strconv.AppendInt(b, i, 10)
return b
},
"bytes.Buffer": func(i int64) []byte {
var b bytes.Buffer
b.WriteString(strconv.FormatInt(i, 10))
b.WriteByte('-')
b.WriteString(strconv.FormatInt(i, 10))
b.WriteByte('-')
b.WriteString(strconv.FormatInt(i, 10))
return b.Bytes()
},
"bytes.Buffer w pool": func(i int64) []byte {
b := bufPool.Get().(*bytes.Buffer)
b.Reset()
b.WriteString(strconv.FormatInt(i, 10))
b.WriteByte('-')
b.WriteString(strconv.FormatInt(i, 10))
b.WriteByte('-')
b.WriteString(strconv.FormatInt(i, 10))
out := make([]byte, b.Len())
copy(out, b.Bytes())
bufPool.Put(b)
return out
},
}
casesString := map[string]benchFuncString{
"fmt": func(i int64) string {
return fmt.Sprintf("%d-%d-%d", i, i, i)
},
"+ + +": func(i int64) string {
return strconv.FormatInt(i, 10) + "-" + strconv.FormatInt(i, 10) + "-" + strconv.FormatInt(i, 10)
},
"strings.Join": func(i int64) string {
return strings.Join([]string{strconv.FormatInt(i, 10), strconv.FormatInt(i, 10), strconv.FormatInt(i, 10)}, "-")
},
}
for name, fn := range casesByte {
out := fn(math.MaxInt64)
if string(out) != exp {
t.Fatal(name, string(out))
}
t.Run(name, func(tb *testing.B) {
for i := int64(0); i < int64(tb.N); i++ {
out = fn(i)
}
})
}
for name, fn := range casesString {
out := fn(math.MaxInt64)
if out != exp {
t.Fatal(name, out)
}
t.Run(name, func(tb *testing.B) {
for i := int64(0); i < int64(tb.N); i++ {
out = fn(i)
}
})
}
}
@GeorgeErickson
Copy link
Author

GeorgeErickson commented Sep 15, 2016

BenchmarkStringBuild/strconv.AppendInt-8            20000000            84.9 ns/op        32 B/op          1 allocs/op
BenchmarkStringBuild/bytes.Buffer-8                 10000000           199 ns/op         135 B/op          4 allocs/op
BenchmarkStringBuild/bytes.Buffer_w_pool-8          10000000           201 ns/op          55 B/op          4 allocs/op
BenchmarkStringBuild/fmt-8                           5000000           257 ns/op          56 B/op          4 allocs/op
BenchmarkStringBuild/+_+_+-8                        10000000           167 ns/op          55 B/op          4 allocs/op
BenchmarkStringBuild/strings.Join-8                 10000000           192 ns/op          87 B/op          5 allocs/op
PASS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment