Rubyレシピブック050〜053途中
050 文字列をバイトごとに処理する
割愛
051 文字列を連結する
なお、短い文字列を大量に追加する場合は、+ではなくString#concatを使うべきです。
なるほど。
Perlは「.」の文字列連結演算子一択だけれど、Rubyは用途によって使い分けが必要らしい。
参照先「060 文字列の末尾に文字列を追加する」にあったベンチマークを手元のマシンでも試してみる。
ただしWindows7にインストールしている1.9.3だ。
plus.rb
buf = "" 50_000.times do buf += "xxx|" end
concat.rb
buf = "" 50_000.times do buf.concat "xxx|" end
$ time /c/Program\ Files\ \(x86\)/Ruby-1.9.3/bin/ruby.exe ~/Desktop/plus.rb real 0m2.886s user 0m0.000s sys 0m0.031s $ time /c/Program\ Files\ \(x86\)/Ruby-1.9.3/bin/ruby.exe ~/Desktop/concat.rb real 0m0.124s user 0m0.000s sys 0m0.031s
約23倍か。Windows版でも挙動は同じだということが確かめられた。
String#concatが破壊的だということも、Yokohama.rbの時に教えてもらえたので、その点だけ注意すれば、基本String#concatで充分なような気もする。
あとその参照先の060が間違った内容だったことも話題になったので書いておく。
concatメソッドと<<演算子の違いは返り値です。concatメソッドは引数を返し、<<演算子はself(追加先の文字列)を返します。
確かに<<演算子はselfというか追加済みの本体の文字列が返ってくるのだけれど、
irb(main):001:0> s = "abc" => "abc" irb(main):002:0> s << "def" => "abcdef"
concatメソッドも同様に追加済みの本体の文字列が返ってくる。引数ではない。
irb(main):001:0> s = "abc" => "abc" irb(main):002:0> s.concat("def") => "abcdef"
ふーむ?