概要
複数の文字を置換するときは strings.Replacer
でまとめて置換した方が早そうな印象がありました。
しかし strings.Replace
のコードの方が -bench
の結果がよい状況に出会したので改めて確認しました。
用語
やりたいこと
ABCDE
の A
を 1
に BC
を 23
に置き換えたいとき
用語
(用語に自信がないので以下の使い方で書きます)
- 「文字」
- 上記やりたいことでいうところの、
A
- 上記やりたいことでいうところの、
- 「文字列」
- 上記やりたいことでいうところの、
BC
- 上記やりたいことでいうところの、
- 「置き換えたい文字(列)」
- 上記やりたいことでいうところの、
A
やBC
- 上記やりたいことでいうところの、
- 「置換対象文字列」
- 上記やりたいことでいうところの、
ABCDE
- 上記やりたいことでいうところの、
さっそくまとめ
以下の場合は strings.Replace
を複数回実行した方が早そうです。
- 「置き換えたい文字(列)」が少ないとき
- 「文字列」を置き換えたいとき
- 「置換対象文字列」に、「置き換えたい文字(列)」が含まれない場合があるとき
ベンチマーク
以下の通り確認しましたが、よくないところがあれば教えてもらえるとうれしいです。
strings.Replaceのベンチマーク.go
const str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"
func BenchmarkStringsReplace(b *testing.B) {
b.Run("2 strings", func(b *testing.B) {
b.Run("Replace all", func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
s := strings.Replace(str, "ABC", "123", -1)
strings.Replace(s, "DEF", "456", -1)
}
})
b.Run("Replace some", func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
s := strings.Replace(str, "ABC", "123", -1)
strings.Replace(s, "456", "___", -1)
}
})
})
}
strings.Replacerのベンチマーク.go
const str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"
func BenchmarkStringsReplacer(b *testing.B) {
b.Run("2 strings", func(b *testing.B) {
b.Run("Replace all.", func(b *testing.B) {
oldnew := []string{
"ABC", "123",
"DEF", "456",
}
r := strings.NewReplacer(oldnew...)
b.ResetTimer()
for i := 0; i < b.N; i++ {
r.Replace(str)
}
})
b.Run("Replace some.", func(b *testing.B) {
oldnew := []string{
"ABC", "123",
"456", "___",
}
r := strings.NewReplacer(oldnew...)
b.ResetTimer()
for i := 0; i < b.N; i++ {
r.Replace(str)
}
})
})
}
BenchmarkStringsReplace/2_strings/Replace_all-8 3911292 305 ns/op 320 B/op 4 allocs/op
BenchmarkStringsReplace/2_strings/Replace_some-8 7506202 164 ns/op 160 B/op 2 allocs/op
BenchmarkStringsReplacer/2_strings/Replace_all.-8 3955276 305 ns/op 192 B/op 3 allocs/op
BenchmarkStringsReplacer/2_strings/Replace_some.-8 4732401 254 ns/op 192 B/op 3 allocs/op
各環境、各バージョンの結果:
https://github.com/abetomo/strings-replace-bench/actions/runs/559930095