Skip to content

Instantly share code, notes, and snippets.

@tailnode
Last active May 28, 2017 14:22
Show Gist options
  • Save tailnode/c593bbac641bc2fb35f01364e778bb5a to your computer and use it in GitHub Desktop.
Save tailnode/c593bbac641bc2fb35f01364e778bb5a to your computer and use it in GitHub Desktop.
// 比较不同情况下不同字符串拼接方法的效率
// 测试函数使用 []string 只是为了方便,在好多情况下要拼接的字符不会在同一个 slice 中
package main
import (
"bytes"
"fmt"
"strings"
"testing"
)
func byFmt(s []string) string {
return fmt.Sprintf("%s%s%s%s", s[0], s[1], s[2], s[3])
}
func byFmtMany(s []string) string {
return fmt.Sprintf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15], s[16], s[17], s[18], s[19], s[20], s[21], s[22], s[23], s[24], s[25], s[26], s[27], s[28], s[29], s[30], s[31], s[32], s[33], s[34], s[35], s[36], s[37], s[38], s[39], s[40], s[41], s[42], s[43], s[44], s[45], s[46], s[47], s[48], s[49], s[50], s[51], s[52], s[53], s[54], s[55], s[56], s[57], s[58], s[59], s[60], s[61], s[62], s[63], s[64], s[65], s[66], s[67], s[68], s[69], s[70], s[71], s[72], s[73], s[74], s[75], s[76], s[77], s[78], s[79], s[80], s[81], s[82], s[83], s[84], s[85], s[86], s[87], s[88], s[89], s[90], s[91], s[92], s[93], s[94], s[95], s[96], s[97], s[98], s[99])
}
func byPlusOnce(s []string) string {
return s[0] + s[1] + s[2] + s[3]
}
func byPlusManyOnce(s []string) string {
return s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7] + s[8] + s[9] + s[10] + s[11] + s[12] + s[13] + s[14] + s[15] + s[16] + s[17] + s[18] + s[19] + s[20] + s[21] + s[22] + s[23] + s[24] + s[25] + s[26] + s[27] + s[28] + s[29] + s[30] + s[31] + s[32] + s[33] + s[34] + s[35] + s[36] + s[37] + s[38] + s[39] + s[40] + s[41] + s[42] + s[43] + s[44] + s[45] + s[46] + s[47] + s[48] + s[49] + s[50] + s[51] + s[52] + s[53] + s[54] + s[55] + s[56] + s[57] + s[58] + s[59] + s[60] + s[61] + s[62] + s[63] + s[64] + s[65] + s[66] + s[67] + s[68] + s[69] + s[70] + s[71] + s[72] + s[73] + s[74] + s[75] + s[76] + s[77] + s[78] + s[79] + s[80] + s[81] + s[82] + s[83] + s[84] + s[85] + s[86] + s[87] + s[88] + s[89] + s[90] + s[91] + s[92] + s[93] + s[94] + s[95] + s[96] + s[97] + s[98] + s[99]
}
func byPlusSplit(s []string) string {
ret := ""
ret += s[0]
ret += s[1]
ret += s[2]
ret += s[3]
return ret
}
func byPlusManySplit(s []string) string {
ret := ""
for i := range s {
ret += s[i]
}
return ret
}
func byBuffer(s []string) string {
buf := bytes.Buffer{}
buf.WriteString(s[0])
buf.WriteString(s[1])
buf.WriteString(s[2])
buf.WriteString(s[3])
return buf.String()
}
func byBufferMany(s []string) string {
buf := bytes.Buffer{}
for i := range s {
buf.WriteString(s[i])
}
return buf.String()
}
func genBenchFunc(f func(s []string) string, s []string) func(b *testing.B) {
return func(bench *testing.B) {
for i := 0; i < bench.N; i++ {
f(s)
}
}
}
func genShortTokens() []string {
return []string{"short", "short", "short", "short"}
}
func genLongTokens() []string {
longToken := strings.Repeat("longstring", 50)
return []string{longToken, longToken, longToken, longToken}
}
func genManyShortTokens() (s []string) {
for i := 0; i < 100; i++ {
s = append(s, "short")
}
return
}
func genManyLongTokens() (s []string) {
longToken := strings.Repeat("longstring", 50)
for i := 0; i < 100; i++ {
s = append(s, longToken)
}
return
}
func BenchmarkConcatShortString(bench *testing.B) {
s := genShortTokens()
bench.Run("fmt", genBenchFunc(byFmt, s))
bench.Run("plusOnce", genBenchFunc(byPlusOnce, s))
bench.Run("plusSplit", genBenchFunc(byPlusSplit, s))
bench.Run("buffer", genBenchFunc(byBuffer, s))
}
func BenchmarkConcatLongString(bench *testing.B) {
s := genLongTokens()
bench.Run("fmt", genBenchFunc(byFmt, s))
bench.Run("plusOnce", genBenchFunc(byPlusOnce, s))
bench.Run("plusSplit", genBenchFunc(byPlusSplit, s))
bench.Run("buffer", genBenchFunc(byBuffer, s))
}
func BenchmarkConcatManyShortString(bench *testing.B) {
s := genManyShortTokens()
bench.Run("fmt", genBenchFunc(byFmtMany, s))
bench.Run("plusOnce", genBenchFunc(byPlusManyOnce, s))
bench.Run("plusSplit", genBenchFunc(byPlusManySplit, s))
bench.Run("buffer", genBenchFunc(byBufferMany, s))
}
func BenchmarkConcatManyLongString(bench *testing.B) {
s := genManyLongTokens()
bench.Run("fmt", genBenchFunc(byFmtMany, s))
bench.Run("plusOnce", genBenchFunc(byPlusManyOnce, s))
bench.Run("plusSplit", genBenchFunc(byPlusManySplit, s))
bench.Run("buffer", genBenchFunc(byBufferMany, s))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment