(一)加号拼接
这种拼接最简单,也最容易被我们使用,在编程过程我们几乎下意识就是使用+好进行拼接。
func StringPlug() string{
var s string
s += "this is string1"
s += "str2"
s += "this is string3"
s += "str4"
return s
}
(二)使用fmt
这种拼接,借助于fmt.Sprint系列函数进行拼接,然后返回拼接的字符串。也是一种非常简单的使用方法,这种方法一般是在用不仅限于字符串的一种格式的场景下使用。
func StringFmtSprintf() string {
return fmt.Sprintf("%s%s%s%s", "this is string1", "str2", "this is string3", "str4")
}
(三)使用Join操作。
这种拼接是用strings.Join()将字符串数组拼接成一个字符串。
func StringJoin() string {
s := []string{"this is string1", "str2", "this is string3", "str4"}
return strings.Join(s, "")
}
(四)用bytes.Buffer拼接
这种被用的也很多,使用的是bytes.Buffer进行的字符串拼接,它是非常灵活的一个结构体,不止可以拼接字符串,还是可以byte,rune等,并且实现了io.Writer接口,写入也非常方便。
func StringBuffer() string {
var b bytes.Buffer
b.WriteString("this is string1")
b.WriteString("str2")
b.WriteString("this is string3")
b.WriteString("str4")
return b.String()
}
(五)用strings.Builder拼接
strings.Builder它的用法几乎和bytsz.Buffer一样。
func StringBuilder() string {
var b strings.Builder
b.WriteString("this is string1")
b.WriteString("str2")
b.WriteString("this is string3")
b.WriteString("str4")
return b.String()
}
(六)性能测试
为了测试几种拼接字符串的方法,我们将上面的函数做一个小小的改变。
func StringPlug2(s []string) string {
var r string
l := len(s)
for i := 0; i < l; i++ {
r += s[i]
}
return r
}
func StringFmtSprintf2(s []interface{}) string {
return fmt.Sprint(s...)
}
func StringJoin2(s []string) string {
return strings.Join(s, "")
}
func StringBuffer2(s []string) string {
var b bytes.Buffer
l := len(s)
for i := 0; i < l; i++ {
b.WriteString(s[i])
}
return b.String()
}
func StringBuilder2(s []string) string {
var b strings.Builder
l := len(s)
for i := 0; i < l; i++ {
b.WriteString(s[i])
}
return b.String()
}
测试函数如下:
const NUM = 1000
var Str string = "this is a long string"
func GetString(n int) []string {
s := make([]string, n)
for i := 0; i < n; i++ {
s[i] = Str
}
return s
}
func BenchmarkStringPlus2(b *testing.B) {
s := GetString(NUM)
b.ResetTimer()
for i := 0; i < b.N; i++ {
StringPlug2(s)
}
}
func BenchmarkFmtSprintf2(b *testing.B) {
s := GetString(NUM)
b.ResetTimer()
in := make([]interface{}, len(s))
for k, v := range s {
in[k] = v
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
StringFmtSprintf2(in)
}
}
func BenchmarkJoin2(b *testing.B) {
s := GetString(NUM)
b.ResetTimer()
for i := 0; i < b.N; i++ {
StringJoin2(s)
}
}
func BenchmarkBuffer2(b *testing.B) {
s := GetString(NUM)
b.ResetTimer()
for i := 0; i < b.N; i++ {
StringBuffer2(s)
}
}
func BenchmarkBuilder2(b *testing.B) {
s := GetString(NUM)
b.ResetTimer()
for i := 0; i < b.N; i++ {
StringBuilder2(s)
}
}
测试结果
goos: linux
goarch: amd64
pkg: gowork/stringjoin
BenchmarkStringPlus2-2 500 2361492 ns/op 11050656 B/op 999 allocs/op
BenchmarkFmtSprintf2-2 30000 43713 ns/op 21767 B/op 1 allocs/op
BenchmarkJoin2-2 100000 20244 ns/op 43520 B/op 2 allocs/op
BenchmarkBuffer2-2 50000 25620 ns/op 66320 B/op 10 allocs/op
BenchmarkBuilder2-2 30000 39369 ns/op 96224 B/op 16 allocs/op
从上面可以看出来性能最好的就是strings.join函数,不过这种一般针对的是字符串数组,很多场景都不适合。我们可以退而求其次采用byts.Buffer 它的运行时间和分配的内存此时都是比较好的。
网友评论