51Reboot 运维开发
Golang 课程1.18开课
K8S 课程
Python 自动化进阶课程
Python 基础实战课程
运维前端课程
课程试听预约请扫码>>>
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yYkdTYzEjZhBTMyIzNilTOyEjYykDN1ATYkNWN0EzYh9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
出处:https://url.cn/5tlJXuW
姿势一览
String Concat
str += "test-string"
String Sprintf
str = fmt.Sprintf("%s%s", str, "test-string")
String Join
str = strings.Join([]string{str, "test-string"}, "")
Buffer Write
buf := new(bytes.Buffer)buf.WriteString("test-string")str := buf.String()
Bytes Append
var b []bytes := "test-string"b = append(b, s...)str := string(b)
String Copy
ts := "test-string"n := 5tsl := len(ts) * nbs := make([]byte, tsl)bl := 0for bl < tsl { bl += copy(bs[bl:], ts)}str := string(bs)
String Builder
从 Go 1.10 版本开始,标准包 strings 提供 strings.Builder:
var builder strings.Builderbuilder.WriteString("test-string")str := builder.String()
Benchmark
性能测试:
package mainimport ( "bytes" "fmt" "strings" "testing")const ( sss = "hello world!" cnt = 10000)var expected = strings.Repeat(sss, cnt)func BenchmarkStringConcat(b *testing.B) { var result string for n := 0; n < b.N; n++ { var str string for i := 0; i < cnt; i++ { str += sss } result = str } b.StopTimer() if result != expected { b.Errorf("unexpected result; got=%s, want=%s", string(result), expected) }}func BenchmarkStringSprintf(b *testing.B) { var result string for n := 0; n < b.N; n++ { var str string for i := 0; i < cnt; i++ { str = fmt.Sprintf("%s%s", str, sss) } result = str } b.StopTimer() if result != expected { b.Errorf("unexpected result; got=%s, want=%s", string(result), expected) }}func BenchmarkStringJoin(b *testing.B) { var result string for n := 0; n < b.N; n++ { var str string for i := 0; i < cnt; i++ { str = strings.Join([]string{str, sss}, "") } result = str } b.StopTimer() if result != expected { b.Errorf("unexpected result; got=%s, want=%s", string(result), expected) }}func BenchmarkBufferWrite(b *testing.B) { var result string for n := 0; n < b.N; n++ { buf := new(bytes.Buffer) for i := 0; i < cnt; i++ { buf.WriteString(sss) } result = buf.String() } b.StopTimer() if result != expected { b.Errorf("unexpected result; got=%s, want=%s", string(result), expected) }}func BenchmarkBytesAppend(b *testing.B) { var result string for n := 0; n < b.N; n++ { var bbb []byte for i := 0; i < cnt; i++ { bbb = append(bbb, sss...) } result = string(bbb) } b.StopTimer() if result != expected { b.Errorf("unexpected result; got=%s, want=%s", string(result), expected) }}func BenchmarkStringCopy(b *testing.B) { var result string for n := 0; n < b.N; n++ { tsl := len(sss) * cnt bs := make([]byte, tsl) bl := 0 for bl < tsl { bl += copy(bs[bl:], sss) } result = string(bs) } b.StopTimer() if result != expected { b.Errorf("unexpected result; got=%s, want=%s", string(result), expected) }}func BenchmarkStringBuilder(b *testing.B) { var result string for n := 0; n < b.N; n++ { var builder strings.Builder for i := 0; i < cnt; i++ { builder.WriteString(sss) } result = builder.String() } b.StopTimer() if result != expected { b.Errorf("unexpected result; got=%s, want=%s", string(result), expected) }}
测试结果:
BenchmarkStringConcat-4 19 61431933 ns/op 632845167 B/op 10005 allocs/opBenchmarkStringSprintf-4 10 109283838 ns/op 1075688336 B/op 29688 allocs/opBenchmarkStringJoin-4 15 75854431 ns/op 632844905 B/op 10003 allocs/opBenchmarkBufferWrite-4 10743 113597 ns/op 441616 B/op 13 allocs/opBenchmarkBytesAppend-4 15578 73796 ns/op 645104 B/op 24 allocs/opBenchmarkStringCopy-4 21416 55761 ns/op 245760 B/op 2 allocs/opBenchmarkStringBuilder-4 15961 74010 ns/op 522224 B/op 23 allocs/op
从测试结果来看,语法中的字符串拼接操作性能是极其低下的,对于操作频繁的大字符串,我们需考虑用更高效的方式替代。
参考资料
- How to efficiently concatenate strings(https://stackoverflow.com/questions/1760757/how-to-efficiently-concatenate-strings)
让我知道你在看