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の方がやっぱいいのかな,と思った.