前言
在日常开发中,写过的最多代码之一就是字符串拼接,比如日志输入拼接,响应参数拼接等等,那么在Golang都有哪些方法来拼接字符串呢?以及他们的效率如何,这次我们就来测试一下。
方式
“+”或”+=”
//字符串相加 func stringPlus(s string, count int) (res string) { for i := 0; i < count; i++ { res += s } return }
fmt内置库
//fmt.Sprintf func stringFmtSprintf(s string, count int) (res string) { for i := 0; i < count; i++ { res = fmt.Sprintf("%s%s", res, s) } return }
bytes.Buffer
//bytes.Buffer func stringBytesBuffer(s string, count int) (res string) { buf := &bytes.Buffer{} for i := 0; i < count; i++ { buf.WriteString(s) } res = buf.String() return }
strings.Builder
//strings.Builder func stringStringsBuilder(s string, count int) (res string) { build := &strings.Builder{} for i := 0; i < count; i++ { build.WriteString(s) } res = build.String() return }
[]byte
//byte切片 func stringByteSlice(s string, count int) (res string) { b := make([]byte, len(s)) for i := 0; i < count; i++ { b = append(b, s...) } res = string(b) return }
性能
上面举例了golang中常见的五种字符串拼接方式,那么他们的拼接性能如何呢?我们来用基准测试测试一下:
package main import "testing" const ( testString = "a" testCount = 1000 ) func BenchmarkStringPlus(b *testing.B) { for i := 0; i < b.N; i++ { stringPlus(testString, testCount) } } func BenchmarkStringFmtSprintf(b *testing.B) { for i := 0; i < b.N; i++ { stringFmtSprintf(testString, testCount) } } func BenchmarkStringBytesBuffer(b *testing.B) { for i := 0; i < b.N; i++ { stringBytesBuffer(testString, testCount) } } func BenchmarkStringStringsBuilder(b *testing.B) { for i := 0; i < b.N; i++ { stringStringsBuilder(testString, testCount) } } func BenchmarkStringByteSlice(b *testing.B) { for i := 0; i < b.N; i++ { stringByteSlice(testString, testCount) } }
结果为:
goos: windows goarch: amd64 pkg: go-juejin/strappend cpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz BenchmarkStringPlus BenchmarkStringPlus-6 9313 129762 ns/op BenchmarkStringFmtSprintf BenchmarkStringFmtSprintf-6 4152 260648 ns/op BenchmarkStringBytesBuffer BenchmarkStringBytesBuffer-6 181897 6579 ns/op BenchmarkStringStringsBuilder BenchmarkStringStringsBuilder-6 280454 4355 ns/op BenchmarkStringByteSlice BenchmarkStringByteSlice-6 925546 1212 ns/op PASS
可见在数据量多的情况下,[]byte
的方式是最优的,fmt.Sprintf
方式性能最差,如果知道字符串长度的话,就优先选择[]byte
的方式。
后记
在不同的情况来选择不同的拼接方式,才能使得我们的效率事半功倍。
最后,感谢您的阅读,谢谢!