【Crystal】文字列結合のパフォーマンス

Crystal

最近、競プロでCrystalを使い始めたので、Rubyとの違いなどをメモとして残しておきます。

Crystalの資料が少ないので、完全に調べきれていないと思います。
もし間違っていたら指摘していただけると助かります。

Crystalの文字列結合

Rubyの文字列結合の最速メソッドはString#<<ですが、Crystalでは少し違うやり方になります。

結論から言うと、String::Buildを使用します。

以下公式リファレンスの説明
https://crystal-lang.org/api/0.33.0/String.html#build(capacity=64,&):self-class-method

与えられた初期容量で String::Builder を作成し、それをブロックに渡し、最後にそこから String を取り出すことによって String を構築する。String::Builder は、必要に応じて自動的にサイズを変更する。

詳細は公式で文字列のパフォーマンスについての記述があるので、そちらに目を通してください。

パフォーマンス - Crystal

パフォーマンス

Crystalで私が思いつく文字列連結方法は以下の4つ

  • String.build
  • IO::Memory.new
  • String#+
  • Array#pushしてからArray#join

この4つの速度を検証していきます。

require "benchmark"

Benchmark.ips do |bm|
  bm.report("String.build") do
    String.build do |io|
      10000.times do
        io << "hello world"
      end
    end
  end

  bm.report("IO::Memory") do
    io = IO::Memory.new
    10000.times do
      io << "hello world"
    end
    io.to_s
  end

  bm.report("String#+") do
    io = ""
    10000.times do
      io += "hello world"
    end
  end

  bm.report("Array#join") do
    io = [] of String
    10000.times do
      io << "hello world"
    end
    io.join
  end
end

結果:String.buildが最速でした。

まとめ

文字列の連結はString.buildを使いましょう。

ちなみにこの記事を書くきっかけになったAtocoderの問題を載せて置きます。
B – Caesar Cipher

1回目にString#+を使用して、TLE。
2回目にArray#joinを使用して、AC。
3回目にString.buildを使用して、AC。一番早かったです。

コメント

タイトルとURLをコピーしました