LoginSignup
22

More than 5 years have passed since last update.

posted at

updated at

Organization

Rubyでベンチマークを取る

はじめに

RubyでベンチマークするのはRuby標準のbenchmarkライブラリを使えば簡単にできます。

さらに、より簡単にベンチマークを取れるbenchmark-ipsというGemもあります。
このGemは、RailsにContributionする際にベンチマークを取る方法として、公式に指定されてもいます。

以下ではこの2つの使い方を簡単に見ていきます。

benchmark-ips

概要

ipsとは"iterations per second"の略になります。

このGemでベンチマークすると「処理回数(イテレーション回数)/秒」を計測してくれます。
次の項で説明するRuby標準のbenchmarkライブラリは自分で実行回数を指定しなければならないのですが、こちらはその手間がなく、かつ処理ごとに何倍の速度差があるかを出してくれるので便利です。

使い方

まずはインストールしましょう

console
$ gem i benchmark-ips

コードの書き方は以下のとおり。(公式から引用・整形)

計測コード
require 'benchmark/ips'

Benchmark.ips do |x|
  x.report("addition") { 1 + 2 }
  x.report("addition2") do |times|
    i = 0
    while i < times
      1 + 2
      i += 1
    end
  end
  x.report("addition3", "1 + 2")
  x.report("addition-test-long-label") { 1 + 2 }

  x.compare!
end

実行結果は以下のようになります

結果
Calculating -------------------------------------
            addition    71.254k i/100ms
           addition2    68.658k i/100ms
           addition3    83.079k i/100ms
addition-test-long-label
                        70.129k i/100ms
-------------------------------------------------
            addition     4.955M (± 8.7%) i/s -     24.155M
           addition2    24.011M (± 9.5%) i/s -    114.246M
           addition3    23.958M (±10.1%) i/s -    115.064M
addition-test-long-label
                         5.014M (± 9.1%) i/s -     24.545M

Comparison:
           addition2: 24011974.8 i/s
           addition3: 23958619.8 i/s - 1.00x slower
addition-test-long-label:  5014756.0 i/s - 4.79x slower
            addition:  4955278.9 i/s - 4.85x slower

reportメソッドにテストの名前(必須ではない)と計測したい処理を渡します。
compare!は必須ではないですが、書いておくと結果に"Comparison"という項目が出来て、
一目で最速の処理や遅い処理は何倍遅いかを表示してくれるので便利です。

設定

細かい挙動は正直よくわかってないのですが、実行時に2つ指定できる設定があります。
timeは計測する時間、warmupはおそらく処理のオーバーヘッドを少なくするために前処理(ウォーミングアップ)の時間を与えるものだと思います。多分

指定方法は以下の2通りのどちらかでやればOK

Benchmark.ips do |x|

  x.config(
    time: 8, # default 5
    warmup: 3 # default 2
  )

  # or

  x.time = 5
  x.warmup = 2

  ## 後略 ##
end

GC

ベンチマークをしている時だけGCを無効にしたい場合も多々あると思いますが、その時は以下のリンク先のコードをコピペしてやれば大体OK

Benchmark

Ruby標準ベンチマークライブラリの使い方は以下のとおり

ipsとの違いはイテレーション回数を指定しなければいけないことと、Benchmark.bmを呼び出すことでしょうか。
基本的にはipsの方が便利なので、そっち使いましょう。

計測コード
require 'benchmark'

n = 10000000
Benchmark.bm(7) do |x| # 引数の7は結果の表示を揃えるためで必須ではないです
  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.100000   0.010000   1.110000 (  1.098665)
times:    1.080000   0.000000   1.080000 (  1.085871)
upto:     1.070000   0.000000   1.070000 (  1.065394)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
22