Golang 字符串拼接方式有:
- 加号连接
- fmt.Sprintf 格式化连接
- strings.Builder 类型
- bytes.Buffer 字节缓存拼接
- byte 数组 append 拼接
- slice to string
- array to string
结论:+号 > array to string > bytes.Buffer > strings.Builder > fmt.Sprintf > slice to string > byte 数组拼接
测试结果如下:
BenchmarkString-16 661976 1709 ns/op
BenchmarkFmtSprintfString-16 619222 1994 ns/op
BenchmarkBuilderString-16 670098 1821 ns/op
BenchmarkByteBufferString-16 677284 1806 ns/op
BenchmarkByteConcatString-16 320 3555811 ns/op
BenchmarkSliceToString-16 600052 2016 ns/op
BenchmarkArrToString-16 694024 1763 ns/op
测试代码如下:
package main
import (
"bytes"
"fmt"
"strconv"
"strings"
"testing"
"time"
)
var tm string
// 1. 直接拼接
func BenchmarkString(b *testing.B) {
for i := 0; i < b.N; i++ {
tm = "STD.V3." +
time.Now().Format("20060102") +
"." +
"app_id" +
"." +
"slot_id" +
"." +
"agent_id" +
"." +
"code_id"
}
}
// 2. fmt.Sprintf("%s",xxxxx)
func BenchmarkFmtSprintfString(b *testing.B) {
for i := 0; i < b.N; i++ {
tm = fmt.Sprintf("STD.V3.%s.%s.%s.%s.%s",
time.Now().Format("20060102"),
"app_id",
"slot_id",
"agent_id",
"code_id",
)
}
}
// 3. string.Builder
func BenchmarkBuilderString(b *testing.B) {
for i := 0; i < b.N; i++ {
var builder strings.Builder
builder.WriteString("STD.V3.")
builder.WriteString(time.Now().Format("20060102"))
builder.WriteString(".")
builder.WriteString("app_id")
builder.WriteString(".")
builder.WriteString("slot_id")
builder.WriteString(".")
builder.WriteString("agent_id")
builder.WriteString(".")
builder.WriteString("code_id")
tm = builder.String()
}
}
// 4. bytes.Builder
func BenchmarkByteBufferString(b *testing.B) {
for i := 0; i < b.N; i++ {
buffer := new(bytes.Buffer)
buffer.WriteString("STD.V3.")
buffer.WriteString(time.Now().Format("20060102"))
buffer.WriteString(".")
buffer.WriteString("app_id")
buffer.WriteString(".")
buffer.WriteString("slot_id")
buffer.WriteString(".")
buffer.WriteString("agent_id")
buffer.WriteString(".")
buffer.WriteString("code_id")
tm = buffer.String()
}
}
// 5. byte 拼接
func BenchmarkByteConcatString(b *testing.B) {
elems := make([]string, 100000, 100000)
for i := 0; i < len(elems); i++ {
elems[i] = strconv.Itoa(i)
}
length := len(elems)
buf := make([]byte, 0, len(elems))
b.ResetTimer()
for i := 0; i < b.N; i++ {
for j := 0; j < length; j++ {
buf = append(buf, elems[j]...)
}
}
b.StopTimer()
}
// 6. slice to string
func BenchmarkSliceToString(b *testing.B) {
for i := 0; i < b.N; i++ {
ks := []string{"STD", "V3"}
ks = append(ks, time.Now().Format("20060102"))
ks = append(ks, "app_id")
ks = append(ks, "slot_id")
ks = append(ks, "agent_id")
ks = append(ks, "code_id")
tm = strings.Join(ks, ".")
}
}
// 7. array to string
func BenchmarkArrToString(b *testing.B) {
for i := 0; i < b.N; i++ {
ks := [...]string{
"STD",
"V3",
time.Now().Format("20060102"),
"app_id",
"slot_id",
"agent_id",
"code_id",
}
tm = strings.Join(ks[:], ".")
}
}