golang: 字串串接 strings.Builder vs bytes.Buffer vs +

在golang原本都利用bytes.Buffer與+來做字串串接, 發現有strings.Builder這個東西,紀錄一下測試結果

先講結論,

+串接比buffer在串接次數很少且長字串下略有優勢(但差異極低,+主要優勢在容易閱讀),串接次數一多的情況下+串接的效能會大幅降低,不要使用+

strings.Builder在各種情況下都有不錯的效能,可以用strings.Builder代替buffer應對不同情境

測試結果與程式碼如下:

測試環境: win10,  go1.11


串接字串長度 = "test"

串接次數 = 5



串接字串長度 = "testtest"

串接次數 = 5


串接字串長度 = "testtesttesttest"

串接次數 = 5


串接字串長度 = "testtesttesttesttesttesttesttesttesttesttesttest"

串接次數 = 5

接下來開始增加串接次數


串接字串長度 = "testtesttesttesttesttesttesttesttesttesttesttest"

串接次數 = 10


串接字串長度 = "testtesttesttesttesttesttesttesttesttesttesttest"

串接次數 = 100


串接字串長度 = "testtesttesttesttesttesttesttesttesttesttesttest"

串接次數 = 10000


串接字串長度 = "test"

串接次數 = 10000


串接字串長度 = "test"

串接次數 = 100


串接字串長度 = "test"

串接次數 = 10


串接字串長度 = "test"

串接次數 = 5

附上程式碼

package string_concatenation

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

var s = "test"

const cnt = 5

func WriteStringByStringBuilder() {
	var builder strings.Builder
	for i := 0; i < cnt; i++ {
		builder.WriteString(s)
	}
	builder.String()
}

func WriteStringByBytesBuffer() {
	var buffer bytes.Buffer
	for i := 0; i < cnt; i++ {
		buffer.WriteString(s)
	}
	buffer.String()
}

func WriteStringsByPlus() {
	var res string
	for i := 0; i < cnt; i++ {
		res += s
	}
}

func BenchmarkWriteStringByStringBuilder(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteStringByStringBuilder()
	}
}
func BenchmarkWriteStringsByBytesBuffer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteStringByBytesBuffer()
	}
}
func BenchmarkWriteStringsByPlus(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteStringsByPlus()
	}
}