【注意】最后更新于 December 22, 2020,文中内容可能已过时,请谨慎使用。
字符串拼接在日常开发中是很常见的需求,而且有多种选择,今天我们就来研究研究哪种性能最好。
常见的拼接方式有以下几种:
+
fmt.Sprintf
strings.Join
bytes.Buffer
strings.Builder
这里直接编写单元测试比较一下性能
源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package string_join
import (
"bytes"
"fmt"
"strings"
)
var a = "hello"
var b = "world"
var c = []string{a, b}
func StringAdd() string {
return a + "," + b
}
func StringSprintf() string {
return fmt.Sprintf("%s,%s", a, b)
}
func StringJoin() string {
return strings.Join(c, ",")
}
func StringBufferWrite() string {
var buf bytes.Buffer
buf.WriteString(a)
buf.WriteString(",")
buf.WriteString(b)
return buf.String()
}
func StringBuilder() string {
var bul strings.Builder
bul.WriteString(a)
bul.WriteString(",")
bul.WriteString(b)
return bul.String()
}
|
编写单元测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
package string_join
import "testing"
func Benchmark_StringAdd(b *testing.B) {
b.StartTimer()
for i := 0; i < b.N; i++ {
StringAdd()
}
b.StopTimer()
}
func Benchmark_StringSprintf(b *testing.B) {
b.StartTimer()
for i := 0; i < b.N; i++ {
StringSprintf()
}
b.StopTimer()
}
func Benchmark_StringJoin(b *testing.B) {
b.StartTimer()
for i := 0; i < b.N; i++ {
StringJoin()
}
b.StopTimer()
}
func Benchmark_StringBufferWrite(b *testing.B) {
b.StartTimer()
for i := 0; i < b.N; i++ {
StringBufferWrite()
}
b.StopTimer()
}
func Benchmark_StringBuilder(b *testing.B) {
b.StartTimer()
for i := 0; i < b.N; i++ {
StringBuilder()
}
b.StopTimer()
}
|
开测: go test -benchmem -run=^$ -bench ^Benchmark_
1
2
3
4
5
6
7
8
9
10
|
$ go test -benchmem -run=^$ -bench ^Benchmark_ .
goos: darwin
goarch: arm64
Benchmark_StringAdd-8 70887246 16.75 ns/op 0 B/op 0 allocs/op
Benchmark_StringSprintf-8 13203135 90.62 ns/op 48 B/op 3 allocs/op
Benchmark_StringJoin-8 46489255 25.75 ns/op 16 B/op 1 allocs/op
Benchmark_StringBufferWrite-8 26262658 45.11 ns/op 80 B/op 2 allocs/op
Benchmark_StringBuilder-8 32878700 35.91 ns/op 24 B/op 2 allocs/op
PASS
ok command-line-arguments 7.003s
|
可以看出来使用+来拼接字符串是性能最优的,然后刨除strings.Join,剩下strings.Builder是最优的选择。
当然上述测试的字符串是很简短的,当字符串变得很长的时候,推荐使用strings.Builder,至于fmt.Sprintf能不用就不要用了。