LoginSignup
4
1

More than 5 years have passed since last update.

frozen-string-literal に対応するときは << を += に変更するより元を配列として扱った方が良さそうです

Posted at

配列に文字列を追加していってjoinするのは遅い?

String#<< メソッドで文字列に文字列を追加していくと破壊的になるので frozen-string-literal を有効にしたときエラーになります。そこで <<+= に置き換えて新しい文字列を作り直すようにしたりしていましたが、変更箇所が多いとやや面倒なので元の変数を配列にして最後に join する方法で対処することもありました。これならたった二箇所の変更で済みます。ただこの配列にする方法は簡単な反面、なんとなく富豪的で遅くなっているような気がしていたので、ちゃんと速度を比較してみました。

結果

RUBY_VERSION # => "2.5.0"
require "active_support/core_ext/benchmark"
def _; "%7.2f ms" % Benchmark.ms { 1000.times { yield } } end
_ { s = ""; 1000.times { s << rand.to_s }; s      } # => "1052.91 ms"
_ { s = []; 1000.times { s << rand.to_s }; s.join } # => "1012.97 ms"
_ { s = ""; 1000.times { s += rand.to_s }; s      } # => "3393.16 ms"

これでわかったのは遅くなってないということです。配列にしてjoinしても破壊的に追加する方法より遅くなってない、むしろちょっと速かったのは意外でした。一方で3番目の新しい文字列を作り直す方法はインスタンスを生成しまくっているせいか差がでてきてます。

まとめ

バッファ的な文字列変数に断片をどんどん追加していくような処理を frozen-string-literal 対応させるときに、速度が重要なとき<<+= に置き換えるのではなく元の変数を配列にするのも一考です。

4
1
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
4
1