Go日常食用之N种字符串拼接方式及性能测试|Go主题月

1,033 阅读2分钟

前言

在日常开发中,写过的最多代码之一就是字符串拼接,比如日志输入拼接,响应参数拼接等等,那么在Golang都有哪些方法来拼接字符串呢?以及他们的效率如何,这次我们就来测试一下。

方式

"+"或"+="

//字符串相加
func stringPlus(s string, count int) (res string) {
	for i := 0; i < count; i++ {
		res += s
	}
	return
}

fmt内置库

//fmt.Sprintf
func stringFmtSprintf(s string, count int) (res string) {
	for i := 0; i < count; i++ {
		res = fmt.Sprintf("%s%s", res, s)
	}
	return
}

bytes.Buffer

//bytes.Buffer
func stringBytesBuffer(s string, count int) (res string) {
	buf := &bytes.Buffer{}
	for i := 0; i < count; i++ {
		buf.WriteString(s)
	}
	res = buf.String()
	return
}

strings.Builder

//strings.Builder
func stringStringsBuilder(s string, count int) (res string) {
	build := &strings.Builder{}
	for i := 0; i < count; i++ {
		build.WriteString(s)
	}
	res = build.String()
	return
}

[]byte

//byte切片
func stringByteSlice(s string, count int) (res string) {
	b := make([]byte, len(s))
	for i := 0; i < count; i++ {
		b = append(b, s...)
	}
	res = string(b)
	return
}

性能

上面举例了golang中常见的五种字符串拼接方式,那么他们的拼接性能如何呢?我们来用基准测试测试一下:

package main

import "testing"

const (
	testString = "a"
	testCount = 1000
)

func BenchmarkStringPlus(b *testing.B) {
	for i := 0; i < b.N; i++ {
		stringPlus(testString, testCount)
	}
}

func BenchmarkStringFmtSprintf(b *testing.B) {
	for i := 0; i < b.N; i++ {
		stringFmtSprintf(testString, testCount)
	}
}

func BenchmarkStringBytesBuffer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		stringBytesBuffer(testString, testCount)
	}
}

func BenchmarkStringStringsBuilder(b *testing.B) {
	for i := 0; i < b.N; i++ {
		stringStringsBuilder(testString, testCount)
	}
}

func BenchmarkStringByteSlice(b *testing.B) {
	for i := 0; i < b.N; i++ {
		stringByteSlice(testString, testCount)
	}
}

结果为:

goos: windows
goarch: amd64
pkg: go-juejin/strappend
cpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
BenchmarkStringPlus
BenchmarkStringPlus-6             	    9313	    129762 ns/op
BenchmarkStringFmtSprintf
BenchmarkStringFmtSprintf-6       	    4152	    260648 ns/op
BenchmarkStringBytesBuffer
BenchmarkStringBytesBuffer-6      	  181897	      6579 ns/op
BenchmarkStringStringsBuilder
BenchmarkStringStringsBuilder-6   	  280454	      4355 ns/op
BenchmarkStringByteSlice
BenchmarkStringByteSlice-6        	  925546	      1212 ns/op
PASS

可见在数据量多的情况下,[]byte的方式是最优的,fmt.Sprintf方式性能最差,如果知道字符串长度的话,就优先选择[]byte的方式。

后记

在不同的情况来选择不同的拼接方式,才能使得我们的效率事半功倍。

最后,感谢您的阅读,谢谢!