浅析go字符串构造方法
go语言字符串构造方法如下:
1.使用+/+=拼接
2.使用fmt.Sprintf
3.使用strings.Join
4.使用strings.Builder
5.使用bytes.Builder
那种方法最为高效,下面做一些基准测试
package concat_string_test
import (
"bytes"
"fmt"
"strings"
"testing"
)
var s = []string{
"let's",
"study",
"go",
"string",
}
func concatStringByOperator(s1 []string) string {
var s string
for _, v := range s1 {
s += v
}
return s
}
func concatStringBySprintf(s1 []string) string {
var s string
for _, v := range s1 {
s = fmt.Sprintf("%s%s", s, v)
}
return s
}
func concatStringByJoin(s1 []string) string {
return strings.Join(s1, "")
}
func concatStringByStringsBuilder(s1 []string) string {
var b strings.Builder
for _, v := range s1 {
b.WriteString(v)
}
return b.String()
}
func concatStringByStringsBuilderWithInitSize(s1 []string) string {
var b strings.Builder
b.Grow(64)
for _, v := range s1 {
b.WriteString(v)
}
return b.String()
}
func concatStringByBytesBuffer(s1 []string) string {
var b bytes.Buffer
for _, v := range s1 {
b.WriteString(v)
}
return b.String()
}
func concatStringByBytesBufferWithInitSize(s1 []string) string {
var b bytes.Buffer
b.Grow(64)
for _, v := range s1 {
b.WriteString(v)
}
return b.String()
}
func BenchmarkConcatStringByOperator(b *testing.B) {
for i := 0; i < b.N; i++ {
concatStringByOperator(s)
}
}
func BenchmarkConcatStringBySprintf(b *testing.B) {
for i := 0; i < b.N; i++ {
concatStringBySprintf(s)
}
}
func BenchmarkConcatStringByJoin(b *testing.B) {
for i := 0; i < b.N; i++ {
concatStringByJoin(s)
}
}
func BenchmarkConcatStringByStringsBuilder(b *testing.B) {
for i := 0; i < b.N; i++ {
concatStringByStringsBuilder(s)
}
}
func BenchmarkConcatStringByStringsBuilderWithInitSize(b *testing.B) {
for i := 0; i < b.N; i++ {
concatStringByStringsBuilderWithInitSize(s)
}
}
func BenchmarkConcatStringByBytesBuffer(b *testing.B) {
for i := 0; i < b.N; i++ {
concatStringByBytesBuffer(s)
}
}
func BenchmarkConcatStringByBytesBufferWithInitSize(b *testing.B) {
for i := 0; i < b.N; i++ {
concatStringByBytesBufferWithInitSize(s)
}
}
goos: windows goarch: amd64 cpu: Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz BenchmarkConcatStringByOperator-20 3052662 447.5 ns/op 56 B/op 3 allocs/op BenchmarkConcatStringBySprintf-20 583248 1841 ns/op 168 B/op 11 allocs/op BenchmarkConcatStringByJoin-20 8016090 165.6 ns/op 24 B/op 1 allocs/op BenchmarkConcatStringByStringsBuilder-20 3769810 269.1 ns/op 56 B/op 3 allocs/op BenchmarkConcatStringByStringsBuilderWithInitSize-20 9135403 157.3 ns/op 64 B/op 1 allocs/op BenchmarkConcatStringByBytesBuffer-20 4153239 284.6 ns/op 88 B/op 2 allocs/op BenchmarkConcatStringByBytesBufferWithInitSize-20 4028841 280.8 ns/op 88 B/op 2 allocs/op PASS ok command-line-arguments 13.366s
从执行结果第三列,即没操作耗时得出结论:
1.做了初始化的strings.Bulider效率最高
2.strings.Join和做了初始化的bytes.Buffer分列二三位
3.未做初始化的strings.Bulider、Bytes.Buffer和操作符连接在第三档次
4.fmt.Sprintf性能最差
由此得出结论:
1.在能预估字符串长度的情况下,使用初始化的strings.Builder连接字符串效率最高
2.strings.Join连接字符串的评价性能最稳定。如果输入的多个字符串是以[]string承载,那么使用strings.Join
3.使用操作符连接字符串的方法最直观自然,在编译器知晓连接字符串的个数的情况下使用这种方法可以得到编译器的优化处理
4.如果有多种不同类型的变量构建特定格式的字符串,最合适的方法是fmt.Sprintf
Go语言基础及实战 文章被收录于专栏
Go语言学习笔记、语法知识、技术要点和个人理解及实战


