前回の記事でbenchmark使えって話だと自己ツッコミしたので、今回の記事ではbenchmarkを試してみる事とします。
対象コードとベンチマーク
require 'date' require 'benchmark' def funcA (Date.new(2013)..Date.new(9999)).lazy.select {|d| d.day == 13 && d.friday?}.take(10).to_a end def funcB (Date.new(2013)..Date.new(9999)).select {|d| d.day == 13 && d.friday?}.take(10) end def friday_the_13th(day) day.day == 13 && day.friday? end def funcC (Date.new(2013)..Date.new(9999)).lazy.select {|d| friday_the_13th(d) }.take(10).to_a end Benchmark.bm(15) do |x| x.report("lazy") {funcA} x.report("non lazy") {funcB} x.report("lazy with func") {funcC} end
結果
$ ruby benchmark.rb user system total real lazy 0.010000 0.000000 0.010000 ( 0.004575) non lazy 3.460000 0.010000 3.470000 ( 3.497499) lazy with func 0.010000 0.000000 0.010000 ( 0.005096)
……なんだこれはタマゲタなぁ……
ものの数行追加するだけで違いがはっきりと分かるようになりました。
その上……今までは早いと思い込んでいた別関数化が、悪影響である事まで判明。*1
ちゃんと試してみるもんですね
参考記録
複数回実行すると、やはり或る程度のバラツキが出ますね。
特に、最初の例は例外的に関数別の方が結果が良くなりました。
$ ruby benchmark.rb user system total real lazy 0.000000 0.000000 0.000000 ( 0.005214) non lazy 3.220000 0.010000 3.230000 ( 3.231910) lazy with func 0.000000 0.000000 0.000000 ( 0.003674) $ ruby benchmark.rb user system total real lazy 0.000000 0.000000 0.000000 ( 0.002276) non lazy 3.280000 0.010000 3.290000 ( 3.296742) lazy with func 0.000000 0.000000 0.000000 ( 0.004000) $ ruby benchmark.rb user system total real lazy 0.010000 0.000000 0.010000 ( 0.002349) non lazy 3.220000 0.010000 3.230000 ( 3.243692) lazy with func 0.010000 0.000000 0.010000 ( 0.004159) $ ruby benchmark.rb user system total real lazy 0.010000 0.000000 0.010000 ( 0.002608) non lazy 3.180000 0.010000 3.190000 ( 3.195488) lazy with func 0.000000 0.000000 0.000000 ( 0.003540) $ ruby benchmark.rb user system total real lazy 0.000000 0.000000 0.000000 ( 0.001655) non lazy 3.230000 0.010000 3.240000 ( 3.256154) lazy with func 0.010000 0.000000 0.010000 ( 0.005210) $ ruby benchmark.rb user system total real lazy 0.000000 0.000000 0.000000 ( 0.002429) non lazy 3.200000 0.010000 3.210000 ( 3.218932) lazy with func 0.010000 0.000000 0.010000 ( 0.002948)
編集記録
- 何度か実行して結果を比較
*1:といっても、優れてる場合も出てるため誤差と言ってしまっても良いレベルですが