前言
在日常开发中,写过的最多代码之一就是字符串拼接,比如日志输入拼接,响应参数拼接等等,那么在 Golang 都有哪些方法来拼接字符串呢?以及他们的效率如何,这次我们就来测试一下。
方式
“+” 或 ”+=”
// 字符串相加func stringPlus(s string, count int) (res string) {for i := 0; i < count; i++ {res += s}return}fmt 内置库
//fmt.Sprintffunc stringFmtSprintf(s string, count int) (res string) {for i := 0; i < count; i++ {res = fmt.Sprintf("%s%s", res, s)}return}bytes.Buffer
//bytes.Bufferfunc 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.Builderfunc 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: windowsgoarch: amd64pkg: go-juejin/strappendcpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHzBenchmarkStringPlusBenchmarkStringPlus-6 9313 129762 ns/opBenchmarkStringFmtSprintfBenchmarkStringFmtSprintf-6 4152 260648 ns/opBenchmarkStringBytesBufferBenchmarkStringBytesBuffer-6 181897 6579 ns/opBenchmarkStringStringsBuilderBenchmarkStringStringsBuilder-6 280454 4355 ns/opBenchmarkStringByteSliceBenchmarkStringByteSlice-6 925546 1212 ns/opPASS
可见在数据量多的情况下,[]byte的方式是最优的,fmt.Sprintf方式性能最差,如果知道字符串长度的话,就优先选择 []byte 的方式。
后记
在不同的情况来选择不同的拼接方式,才能使得我们的效率事半功倍。
最后,感谢您的阅读,谢谢!