最近、パフォーマンスの最適化が行われています。時間がかかる機能がありますが、その中の操作のほとんどは文字列スプライシング操作のようで、実際にはgolangでの文字列スプライシングの実装がたくさんあります。
実装
1.演算子を直接使用する
func BenchmarkAddStringWithOperator(b *testing.B) {
hello := "hello"
world := "world"
for i := 0; i < b.N; i++ {
_ = hello + "," + world
}
}
golangの文字列は不変です。すべての操作で新しい文字列が生成されるため、一時的に役に立たない文字列が多数生成されます。それらは役に立たないだけでなく、gcに余分な負担をかけるため、パフォーマンスの比較の違いがあります。
2.fmt.Sprintf()
func BenchmarkAddStringWithSprintf(b *testing.B) {
hello := "hello"
world := "world"
for i := 0; i < b.N; i++ {
_ = fmt.Sprintf("%s,%s", hello, world)
}
}
多くの一時文字列を生成する直接演算子とは異なり、内部的に[] byteで実装されますが、内部ロジックはより複雑で、余分な判断が多く、インターフェイスが使用されるため、パフォーマンスはあまり良くありません。
3.strings.Join()
func BenchmarkAddStringWithJoin(b *testing.B) {
hello := "hello"
world := "world"
for i := 0; i < b.N; i++ {
_ = strings.Join([]string{hello, world}, ",")
}
}
結合は、最初に文字列配列の内容に基づいてスプライスされた文字列の長さを計算し、次に対応するメモリサイズを適用し、1つの文字列を1つずつ入力します。配列の場合、この効率は次のようになります非常に高いですが、もともといいえ、このデータを構築するコストは小さくありません
4.buffer.WriteString()
func BenchmarkAddStringWithBuffer(b *testing.B) {
hello := "hello"
world := "world"
for i := 0; i < 1000; i++ {
var buffer bytes.Buffer
buffer.WriteString(hello)
buffer.WriteString(",")
buffer.WriteString(world)
_ = buffer.String()
}
}
これは理想的です。可変文字として使用でき、メモリの増加に最適化できます。文字列の長さを見積もることができる場合は、buffer.Grow()インターフェイスを使用して容量を設定することもできます。
試験結果
BenchmarkAddStringWithOperator-8 50000000 30.3 ns/op
BenchmarkAddStringWithSprintf-8 5000000 261 ns/op
BenchmarkAddStringWithJoin-8 30000000 58.7 ns/op
BenchmarkAddStringWithBuffer-8 2000000000 0.00 ns/op
これは私自身のMacで実行した結果です。goバージョンgoバージョンgo1.8darwin / amd64、この結果は参照用です。実際の本番環境の値に基づいている必要があります。コードはhttps:// githubにあります。 .com /hatlonely/hellogolang/blob/master/internal/buildin/string_test.go
主な結論
- 既存の文字列配列の場合、使用
strings.Join()
するとパフォーマンスが向上する 可能性があります - パフォーマンス要件が高い場合は、それを使用し
buffer.WriteString()
てパフォーマンスを向上させてください - パフォーマンス要件がそれほど高くない場合は、演算子を直接使用すると、コードが短く明確になり、読みやすさが向上します。
- 文字列だけでなく、数字などの他のニーズもスプライスする必要がある場合は、検討することができます
fmt.Sprintf()
参照リンク
go言語の文字列連結のパフォーマンス分析:http: //herman.asia/efficient-string-concatenation-in-go
この記事は、短い本の記事から複製されています:Golangのいくつかの文字列接続方法