Rubyにコードの範囲を指定して処理時間を計測する便利クラス「Benchmark」があります(今日知りました)。使い方は以下のような感じです。
require 'benchmark' puts Benchmark.measure { for i in 1..1000 puts 'hello' end } puts Benchmark::CAPTION
実行結果は以下の通りです。
0.000000 0.000000 0.000000 ( 0.005730)
user system total real
これはいい!と思ったのですが、何度も呼ばれる処理の場合、計測結果が何度も表示されてしまいます。合計が知りたいのに。。。そこでこのありがたいBenchmarkクラスの処理結果をいじって合計を求めるクラスを作りました。処理時間は上記の通り、短すぎると0になってしまいますのでrealtimeを使うことにします。
■benchmark_sum.rb
class Benchmark_sum @@total_time = {} @@total_times = {} def self.add(s) begin @@total_time[current_method] += s.to_f @@total_times[current_method] += 1 rescue NoMethodError @@total_time[current_method] = 0.0 @@total_times[current_method] = 0 retry end end def self.result @@total_time.each {|k,v| puts k+": " + v.to_s + ' ' + @@total_times[k].to_s} end end class Object def current_method caller[1].scan(/`(.*)'/).to_s end end
使い方は以下のような感じです。
require 'benchmark' require 'benchmark_sum' def a data = [] Benchmark_sum.add( Benchmark.realtime { for i in 1..100 data << rand(1000) end bubblesort(data) }) end #http://d.hatena.ne.jp/yasutomo57jp/20080819/1219141752 より拝借させていただきました。 def bubblesort(array) Benchmark_sum.add( Benchmark.realtime { for i in 0...array.length-1 for j in 0...array.length-1-i array[j+1],array[j]=array[j],array[j+1] if array[j] > array[j+1] end end }) return array end 100.times {a} Benchmark_sum.result
実行結果は以下の通りです。見方は最初がメソッド名、次が処理時間の合計、最後が呼び出し回数です。
a: 0.929216146469116 100
bubblesort: 0.921257495880127 100
ちなみにBenchmark_sumはメソッドの処理時間を計測することを前提としています。同一メソッド内にBenchmarkを複数入れるにはメソッド名を自動取得にせず手動で都度与えるように変更すればいいと思います。