Goalng 字符串拼接及其性能

(一)加号拼接

这种拼接最简单,也最容易被我们使用,在编程过程我们几乎下意识就是使用+好进行拼接。

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 它的运行时间和分配的内存此时都是比较好的。

你可能感兴趣的:(Goalng 字符串拼接及其性能)