(一)加號拼接
這種拼接最簡單典格,也最容易被我們使用,在編程過程我們幾乎下意識就是使用+好進行拼接。
func StringPlug() string{
var s string
s += "this is string1"
s += "str2"
s += "this is string3"
s += "str4"
return s
}
(二)使用fmt
這種拼接掷倔,借助于fmt.Sprint系列函數(shù)進行拼接,然后返回拼接的字符串个绍。也是一種非常簡單的使用方法勒葱,這種方法一般是在用不僅限于字符串的一種格式的場景下使用。
func StringFmtSprintf() string {
return fmt.Sprintf("%s%s%s%s", "this is string1", "str2", "this is string3", "str4")
}
(三)使用Join操作巴柿。
這種拼接是用strings.Join()將字符串數(shù)組拼接成一個字符串凛虽。
func StringJoin() string {
s := []string{"this is string1", "str2", "this is string3", "str4"}
return strings.Join(s, "")
}
(四)用bytes.Buffer拼接
這種被用的也很多,使用的是bytes.Buffer進行的字符串拼接广恢,它是非常靈活的一個結(jié)構(gòu)體凯旋,不止可以拼接字符串,還是可以byte,rune等钉迷,并且實現(xiàn)了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()
}
(六)性能測試
為了測試幾種拼接字符串的方法睡蟋,我們將上面的函數(shù)做一個小小的改變。
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()
}
測試函數(shù)如下:
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)
}
}
測試結(jié)果
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函數(shù)枷颊,不過這種一般針對的是字符串數(shù)組戳杀,很多場景都不適合。我們可以退而求其次采用byts.Buffer 它的運行時間和分配的內(nèi)存此時都是比較好的夭苗。