go 语言中哪种字符串拼接的方式最高效?

go 语言中字符串拼接有好几种方式,从最普通的+拼接到buffer字节缓冲都有.但是如果遇到大量的字符串拼接的情况,他们之间的性能差异还是需要注意的.

常用的字符串拼接方式

测试代码

因为 go 语言自带了很好用的 benchmark 测试框架,因此我们可以写一个简单的测试用例,具体代码如下:

package main

import (
    "bytes"
    "strings"
    "testing"
)

var (
    strs = []string{
        "one",
        "two",
        "three",
        "four",
        "five",
        "一",
        "二",
        "三",
        "四",
        "五",
    }
)

func Benchmark_strConcat(b *testing.B) {
    for i := 0; i < b.N; i++ {
        var (
            s string
        )
        for _, str := range strs {
            s += str
        }
    }
}

func Benchmark_strJoin(b *testing.B) {
    for i := 0; i <= b.N; i++ {
        strings.Join(strs, "")
    }
}

func Benchmark_strByte(b *testing.B) {
    for i := 0; i < b.N; i++ {
        var (
            s []byte
        )
        for _, str := range strs {
            s = append(s, []byte(str)...)
        }
        _ = string(s)
    }
}

func Benchmark_strBuff(b *testing.B) {
    for i := 0; i < b.N; i++ {
        var (
            buf bytes.Buffer
        )
        for _, str := range strs {
            buf.WriteString(str)
        }
        buf.String()
    }
}

测试结果

测试结果如下

    Benchmark_strConcat-8        3000000           663 ns/op
    
    Benchmark_strJoin-8         10000000           204 ns/op
    
    Benchmark_strByte-8          5000000           372 ns/op
    
    Benchmark_strBuff-8          5000000           271 ns/op
    PASS
    ok      test/string 8.738s  

可见最慢的就是直接用+号拼接,最快的是strings.join().不过strings.join()对数据格式有要求,组装[]string还需要做额外的操作. 而bytes.Buffer相比之下使用方便,而且附带很多有用的函数,比如truncate()等. 因此日常使用还是推荐bytes.Buffer.

Comments

comments powered by Disqus