rubyでメソッドの処理速度をはかるとき

rubyで処理速度をはかる時は以下のようにbenchmarkモジュールを使います。
で、この前Railsのコミットログを眺めていたら、gsubメソッドをtrに置き換えたというのがあったので、
試しに以下のように処理の計測を行ってみました。

require 'benchmark'

hoge = 'aaaaaabbbbbceerwrrweqgaga123rgurwfkja'

n = 50
Benchmark.bm do |x|
  # fast
  x.report { n.times { hoge.tr('aa', 'xx') } }
  # slow
  x.report { n.times { hoge.gsub('aa', 'xx') } }
end

で、何回か流したのですが、結果は以下のようにtrの方が確かに早いですね。


1回目
user system total real
0.000000 0.000000 0.000000 ( 0.000039)
0.000000 0.000000 0.000000 ( 0.000166)
2回目
user system total real
0.000000 0.000000 0.000000 ( 0.000041)
0.000000 0.000000 0.000000 ( 0.000153)
3回目
user system total real
0.000000 0.000000 0.000000 ( 0.000038)
0.000000 0.000000 0.000000 ( 0.000134)
4回目
user system total real
0.000000 0.000000 0.000000 ( 0.000037)
0.000000 0.000000 0.000000 ( 0.000113)

一番左の値が実際の計測時間になります。
で、それ以外にも書き方によっては速い遅いがあって以下のようにコードを書き換えて幾つか検証してみました

require 'benchmark'

hoge = 'aaaaaabbbbbceerwrrweqgaga123rgurwfkja'

n = 50
Benchmark.bm do |x|
  # fast
  x.report('fast') { n.times { hoge.tr('aa', 'xx') } }
  # slow
  x.report('slow') { n.times { hoge.gsub('aa', 'xx') } }
end

Benchmark.bm do |x|
  # fast
  x.report('fast') { n.times { hoge.sub('aa', 'xx') } }
  # slow
  x.report('slow') { n.times { hoge.gsub('aa', 'xx') } }
end

h = { a: 1, b: 2, c: 3 }
Benchmark.bm do |x|
  # fast
  x.report('fast') { n.times { h.each_key { |k| k } } }
  # slow
  x.report('slow') { n.times { h.keys.each { |k| k } } }
end

Benchmark.bm do |x|
  # fast
  x.report('fast') { n.times { a = 1; b =  2  } }
  # slow
  x.report('slow') { n.times {  a, b = 1, 2  } }
end

結果は


user system total real
fast 0.000000 0.000000 0.000000 ( 0.000092)
slow 0.000000 0.000000 0.000000 ( 0.000132)
user system total real
fast 0.000000 0.000000 0.000000 ( 0.000058)
slow 0.000000 0.000000 0.000000 ( 0.000134)
user system total real
fast 0.000000 0.000000 0.000000 ( 0.000018)
slow 0.000000 0.000000 0.000000 ( 0.000019)
user system total real
fast 0.000000 0.000000 0.000000 ( 0.000005)
slow 0.000000 0.000000 0.000000 ( 0.000034)

なるほど、勉強になります。