1
0

More than 3 years have passed since last update.

strings.Replace と strings.Replacer はどっちが早い

Last updated at Posted at 2021-02-12

概要

複数の文字を置換するときは strings.Replacer でまとめて置換した方が早そうな印象がありました。
しかし strings.Replace のコードの方が -bench の結果がよい状況に出会したので改めて確認しました。

用語

やりたいこと

ABCDEA1BC23 に置き換えたいとき

用語

(用語に自信がないので以下の使い方で書きます)

  • 「文字」
    • 上記やりたいことでいうところの、A
  • 「文字列」
    • 上記やりたいことでいうところの、BC
  • 「置き換えたい文字(列)」
    • 上記やりたいことでいうところの、ABC
  • 「置換対象文字列」
    • 上記やりたいことでいうところの、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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0