Rubyでの無限ループのカウント

無限ループ内でループ回数を数えるメモ - まめ畑
こんな方法もあるのか,と思い気になったので測ってみた.

Rehearsal -------------------------------------------------
loop 10000000   8.688000   0.000000   8.688000 (  8.922000)
upto 10000000  21.453000   0.000000  21.453000 ( 21.750000)
--------------------------------------- total: 30.141000sec

                    user     system      total        real
loop 10000000   8.828000   0.015000   8.843000 (  8.937000)
upto 10000000  21.406000   0.000000  21.406000 ( 22.000000)
Rehearsal -------------------------------------------------
loop 10000000   6.172000   0.000000   6.172000 (  6.234375)
upto 10000000   0.000000   0.000000   0.000000 (  0.000000)
---------------------------------------- total: 6.172000sec

                    user     system      total        real
loop 10000000   6.093000   0.000000   6.093000 (  6.234375)
upto 10000000   0.000000   0.000000   0.000000 (  0.000000)

予想通りloopの方が速かったんだけど,1.9だとそもそもループが回らないという.MacBookの1.8.6で測ったら5秒くらいの差だったんだけども,アーキテクチャにそこまで依存してるのか?ソース追うのが面倒なので,原因究明は放置^^;
以下ソース(rosylillyの中身替えただけ).

require 'benchmark'

n = 10000000

Benchmark::bmbm { |x|
  x.report("loop #{n}") {
    count = 0
    loop do
      break if count == n
      count += 1
    end
  }
  x.report("upto #{n}") {
    0.upto(0/(0.0)) do |count|
      break if count == n
    end
  }
}

追記

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/45744
元ネタはMLということで探したら見つかった.1.9で回らないのはどんな違いがあるんだろうとソース読もうとしたけど,rb_call0まで行った所で比較が面倒になって止めた.とりあえずuptoが遅いのはrb_funcallの呼び出しが重なるからっぽい.でも,uptoに整数渡す場合はuptoの方が速い.rb_call0を直接loopは呼んでるからその分速いのかなぁとか思ったけど,CHECK_INTSの分遅いのかな?
そう言えば,これと直接は関係ないけどloopとwhile trueだとwhile trueの方がちょっと速い.これはloopがイテレータ呼び出しだからと思うんだけど,StopIterationの関係もあるし,ちょっと遅いけど1.9だとloopの方がやっぱいいのかな,と思った.