寻找golang中最高效的字符串连接函数-创新互联

以下五个字符串连接函数,你认为哪一个最快?

创新互联专注于企业营销型网站、网站重做改版、宝应网站定制设计、自适应品牌网站建设、HTML5商城系统网站开发、集团公司官网建设、成都外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为宝应等各大城市提供网站开发制作服务。
func StrConcat1(strs []string) (string) {
    var str string
    for _, value := range strs {
        str += value
    }
    return str
}

func StrConcat2(strs []string) (string) {
    if len(strs) == 0 {
        return ""
    }
    b := bytes.Buffer{}
    for _, s := range strs {
        b.WriteString(s)
    }
    return b.String()
}

func StrConcat3(strs []string) (string) {
    return strings.Join(strs, "")
}

func StrConcat4(strs []string) (string) {
    var data []byte
    for _, value := range strs {
        data = append(data, value...)
    }
    return string(data)
}

func StrConcat5(strs []string) (string) {
    var length int
    for _, s := range strs {
        length += len(s)
    }
    bs := make([]byte, length)
    var i int
    for _, value := range strs {
        i += copy(bs[i:], value)
    }
    return string(bs[:])
}

编写如下的测试文件

import "testing"

var TestStr = []string{"hello", "world", "my", "god", "this", "is", "big", "content"}

func Benchmark_StrConcat1(b *testing.B)  {
    for i := 0; i < b.N ; i++ {
        StrConcat1(TestStr)
    }
}

func Benchmark_StrConcat2(b *testing.B)  {
    for i := 0; i < b.N ; i++ {
        StrConcat2(TestStr)
    }
}

func Benchmark_StrConcat3(b *testing.B)  {
    for i := 0; i < b.N ; i++ {
        StrConcat3(TestStr)
    }
}

func Benchmark_StrConcat4(b *testing.B)  {
    for i := 0; i < b.N ; i++ {
        StrConcat4(TestStr)
    }
}

func Benchmark_StrConcat5(b *testing.B)  {
    for i := 0; i < b.N ; i++ {
        StrConcat5(TestStr)
    }
}

然后执行测试命令

go test -test.bench=".*"

执行结果如下:

Benchmark_StrConcat1-4       5000000           366 ns/op
Benchmark_StrConcat2-4      10000000           178 ns/op
Benchmark_StrConcat3-4      10000000           127 ns/op
Benchmark_StrConcat4-4      10000000           178 ns/op
Benchmark_StrConcat5-4      20000000           102 ns/op

可见,第5个函数的效率是最高的,虽然它的代码量最多。
其次是第3个函数,其实我们查看第3个函数的源代码就可以发现,它与第5个函数本质上是一样的,但是因为多了对分隔符的拷贝操作,执行时间增加了。我认为这个系统函数可以再优化,判断分隔符是不是空的,如果是空的,就按第5个函数那个处理,这样效率还能提升15%。

附,strings.Join函数源代码:

// Join concatenates the elements of a to create a single string. The separator string
// sep is placed between elements in the resulting string.
func Join(a []string, sep string) string {
    switch len(a) {
    case 0:
        return ""
    case 1:
        return a[0]
    case 2:
        // Special case for common small values.
        // Remove if golang.org/issue/6714 is fixed
        return a[0] + sep + a[1]
    case 3:
        // Special case for common small values.
        // Remove if golang.org/issue/6714 is fixed
        return a[0] + sep + a[1] + sep + a[2]
    }
    n := len(sep) * (len(a) - 1)
    for i := 0; i < len(a); i++ {
        n += len(a[i])
    }

    b := make([]byte, n)
    bp := copy(b, a[0])
    for _, s := range a[1:] {
        bp += copy(b[bp:], sep)
        bp += copy(b[bp:], s)
    }
    return string(b)
}

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


本文名称:寻找golang中最高效的字符串连接函数-创新互联
当前地址:http://abwzjs.com/article/cccpgo.html