ベンチマークを取るためのモジュールです。
benchmark(caption = "", label_width = nil, fmtstr = nil, *labels) {|rep| ...} -> bool[permalink][rdoc]Benchmark::Report オブジェクトを生成し、それを引数として与えられたブロックを実行します。
基本的には以下のように使います。ブロックが Benchmark::Tms オブジェクトの配列を返した場合は、それらの数値も追加の行に表示されます。
フォーマット文字列として以下が使用できます。
user CPU time で置き換えられます。Benchmark::Tms#utime
system CPU time で置き換えられます(Mnemonic: y of "s*y*stem")。Benchmark::Tms#stime
子プロセスの user CPU time で置き換えられます。Benchmark::Tms#cutime
子プロセスの system CPU time で置き換えられます。Benchmark::Tms#cstime
total CPU time で置き換えられます。Benchmark::Tms#total
実経過時間で置き換えられます。Benchmark::Tms#real
ラベルで置き換えられます(Mnemonic: n of "*n*ame")。Benchmark::Tms#label
require 'benchmark'
n = 50000
# これは
#    Benchmark.bm(7, ">total:", ">avg:") do |x| ... end
# と同じ
Benchmark.benchmark(" "*7 + Benchmark::CAPTION,
                    7,
                    Benchmark::FMTSTR,
                    ">total:",
                    ">avg:") do |x|
  tf = x.report("for:")   { for i in 1..n; a = "1"; end }
  tt = x.report("times:") { n.times do   ; a = "1"; end }
  tu = x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
  [tf+tt+tu, (tf+tt+tu)/3]
end
#=>
             user     system      total        real
for:     1.016667   0.016667   1.033333 (  0.485749)
times:   1.450000   0.016667   1.466667 (  0.681367)
upto:    1.533333   0.000000   1.533333 (  0.722166)
>total:  4.000000   0.033333   4.033333 (  1.889282)
>avg:    1.333333   0.011111   1.344444 (  0.629761)
bm(label_width = 0, *labels) {|rep| ... } -> bool[permalink][rdoc]Benchmark.#benchmark メソッドの引数を簡略化したものです。
Benchmark.#benchmark メソッドと同様に働きます。
例:
require 'benchmark'
n = 50000
Benchmark.bm do |x|
  x.report { for i in 1..n; a = "1"; end }
  x.report { n.times do   ; a = "1"; end }
  x.report { 1.upto(n) do ; a = "1"; end }
end
#=>
      user     system      total        real
  1.033333   0.016667   1.016667 (  0.492106)
  1.483333   0.000000   1.483333 (  0.694605)
  1.516667   0.000000   1.516667 (  0.711077)
以下のようにも書けます。
require 'benchmark'
n = 50000
Benchmark.bm(7) do |x|
  x.report("for:")   { for i in 1..n; a = "1"; end }
  x.report("times:") { n.times do   ; a = "1"; end }
  x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
end
#=>
             user     system      total        real
for:     1.050000   0.000000   1.050000 (  0.503462)
times:   1.533333   0.016667   1.550000 (  0.735473)
upto:    1.500000   0.016667   1.516667 (  0.711239)
集計を付けた場合
require 'benchmark'
n = 50000
Benchmark.bm(7) do |x|
  tf = x.report("for:")   { for i in 1..n; a = "1"; end }
  tt = x.report("times:") { n.times do   ; a = "1"; end }
  tu = x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
  [tf + tt + tu, (tf + tt + tu) / 3]
end
#=>
             user     system      total        real
for:     0.040000   0.000000   0.040000 (  0.141902)
times:   0.010000   0.000000   0.010000 (  0.043335)
upto:    0.020000   0.000000   0.020000 (  0.089806)
>total:  0.070000   0.000000   0.070000 (  0.275044)
>avg:    0.023333   0.000000   0.023333 (  0.091681)
[SEE_ALSO] Benchmark.#benchmark
bmbm(width = 0) {|job| ... } -> [Benchmark::Tms][permalink][rdoc]Benchmark::Job オブジェクトを生成して、それを引数として与えられたブロックを実行します。
ベンチマークの結果は GC の影響によって歪められてしまうことがあります。このメソッドは与えられたブロックを二度実行する事によってこの影響を最小化します。一回目は実行環境を安定化するためにリハーサルとして実行します。二回目は本番として実行します。
二回目のブロック実行の前に GC.start を実行しますが、この実行時間は計測には含まれません。しかし、実際にはこのメソッドを使用しても、GC などの影響を分離することは保証されません。
require 'benchmark'
array = (1..1000000).map { rand }
Benchmark.bmbm do |x|
  x.report("sort!") { array.dup.sort! }
  x.report("sort")  { array.dup.sort  }
end
#=>
Rehearsal -----------------------------------------
sort!  11.928000   0.010000  11.938000 ( 12.756000)
sort   13.048000   0.020000  13.068000 ( 13.857000)
------------------------------- total: 25.006000sec
            user     system      total        real
sort!  12.959000   0.010000  12.969000 ( 13.793000)
sort   12.007000   0.000000  12.007000 ( 12.791000)
measure(label = "") { ... } -> Benchmark::Tms[permalink][rdoc]与えられたブロックを実行して、経過した時間を Process.#times で計り、 Benchmark::Tms オブジェクトを生成して返します。
Benchmark::Tms オブジェクトには to_s が定義されているので、基本的には以下のように使います。
require 'benchmark'
puts Benchmark::CAPTION
puts Benchmark.measure { "a"*1_000_000 }
#=>
    user     system      total        real
1.166667   0.050000   1.216667 (  0.571355)
realtime { ... } -> Float[permalink][rdoc]与えられたブロックを評価して実行時間を計測して返します。
BENCHMARK_VERSION -> String[permalink][rdoc]benchmark ライブラリのバージョンを表します。
CAPTION -> String[permalink][rdoc]Benchmark.#bm の内部などで使用されます。
実際の定義は Benchmark::Tms::CAPTION でされています。
[SEE_ALSO] Benchmark::Tms::CAPTION
FORMAT -> String[permalink][rdoc]Benchmark.#benchmark の第三引数のデフォルト値。
user CPU time で置き換えられます。Benchmark::Tms#utime
system CPU time で置き換えられます(Mnemonic: y of "s*y*stem")。Benchmark::Tms#stime
子プロセスの user CPU time で置き換えられます。Benchmark::Tms#cutime
子プロセスの system CPU time で置き換えられます。Benchmark::Tms#cstime
total CPU time で置き換えられます。Benchmark::Tms#total
実経過時間で置き換えられます。Benchmark::Tms#real
ラベルで置き換えられます(Mnemonic: n of "*n*ame")。Benchmark::Tms#label
上記のフォーマット文字列を使用しています。この定数の内容は以下の通りです。
"%10.6u %10.6y %10.6t %10.6r\n"
[SEE_ALSO] Benchmark.#benchmark, Benchmark::Tms::FORMAT