Rubyが遅いのは本当にBoxingのせいか?

HotRubyがYARVより速いのはBoxingのせい、ということのようです。ベンチマークと言うのが何をさしているのか分かりませんが、とりあえずHotRubyのサイトのStringのベンチマークを対象として考えます。
それはこんなベンチマークです。

startTime = Time.new.to_f
  
sum = ""
50000.times{|e| sum += e.to_s}
  
endTime = Time.new.to_f
puts (endTime - startTime).to_s + ' sec'


本当にBoxingのせいなんでしょうか?
結論から言うとそんなことはないのではないか?って感じです。

もともとRubyのプリミティブ型はソースコード中で特別扱いされていたし(1.8しか見てませんが)、C言語レベルで考えられる中ではそこそこ高速化してました。

HotRubyのサイトにあるStringのベンチマークは海外のブログでも取り上げられて、その時にツッコミを喰らってます。

http://ejohn.org/blog/ruby-vm-in-javascript/

with "<<" and you'll see that Ruby is 10x faster than the HotRuby version.

実際、+=を<<に変えるとRubyは爆速です。(Rubyは1.8.6を使っています)

#+=のとき
7.21914291381836 sec

# <<のとき
0.135228872299194 sec

なんだか、桁が違います。

ただ、<<は破壊的なメソッドなので、YARVのオブジェクト生成に時間がかかる可能性は否定できません。

ついでに、下記のようにしても速いです。

startTime = Time.new.to_f

sum = " "*(40000*5+9000*4+900*3+90*2+10)
i=0
50000.times{|e| e_str=e.to_s; sum[i...i+e_str.length]=e_str; i+=e_str.length  }

endTime = Time.new.to_f
puts (endTime - startTime).to_s + ' sec'

#実行結果
0.345652103424072 sec

領域を最初に確保してあげると、それなりの速さになります。e.to_sでStringを大量に生成しても遅くならないわけですから、Stringの生成で遅くなっている気がしません。

さらに、HotRubyのサイトにあるスクリプト(String#+を使う)場合に、合計50000回実行するのを10000回ごとに区切って実行時間を表示してみます。

#実行結果
0.266942024230957 sec #最初の10000回
0.818481922149658 sec #10000-20000回
1.30647802352905 sec  #20000-30000回
1.76571893692017 sec  #30000-40000回
2.35495710372925 sec  #40000-50000回

だんだんと時間がかかってきているということは、結局はString#newで他よりも大きい範囲のメモリコピーが多発してしまっている、ということのような気がします。

さらにちなみに、同じものをHotRuby上で実行するとこうなります。

0.7890000343322754 sec
0.7769999504089355 sec
0.7820000648498535 sec
0.7790000438690186 sec
0.7779998779296875 sec

時間が一定です。すごくおもしろいですね。