web-dev-qa-db-ja.com

Rubyメソッドの測定とベンチマーク時間

メソッドとRubyのそのメソッドの個々のステートメントにかかる時間をどのように測定できますか?以下のメソッドが表示される場合、メソッドにかかった合計時間と、データベースアクセスとredisアクセスにかかった時間を測定します。すべてのステートメントの前にBenchmark.measureを書きたくありません。 Rubyインタープリターはこれを行うためのフックを提供しますか?

def foo
# code to access database
# code to access redis. 
end
72
Phani

Timeオブジェクトを使用できます。 ( Time Docs

例えば、

start = Time.now
# code to time
finish = Time.now

diff = finish - start

diffは、浮動小数点数としての秒単位です。

編集:endは予約されています。

101
wquist

最も簡単な方法:

require 'benchmark'

def foo
 time = Benchmark.measure {
  code to test
 }
 puts time.real #or save it to logs
end

サンプル出力:

2.2.3 :001 > foo
  5.230000   0.020000   5.250000 (  5.274806)

値は、CPU時間、システム時間、合計および実際の経過時間です。

ソース: Ruby docs

83

ベンチマークのレポートを使用する

require 'benchmark' # Might be necessary.

def foo
  Benchmark.bm(20) do |bm|  # The 20 is the width of the first column in the output.
    bm.report("Access Database:") do 
      # Code to access database.
    end

    bm.report("Access Redis:") do
      # Code to access redis.
    end
  end
end

これにより、次のようなものが出力されます。

                        user     system      total        real
Access Database:    0.020000   0.000000   0.020000 (  0.475375)
Access Redis:       0.000000   0.000000   0.000000 (  0.000037)

<------ 20 ------->  # This is where the 20 comes in. NOTE: Not shown in output.

詳細情報を見つけることができます ここ

25
Joshua Pinter

考え直して、measure()関数をRubyコードブロック引数と一緒に定義すると、時間測定コードを簡素化できます。

def measure(&block)
  start = Time.now
  block.call
  Time.now - start
end

# t1 and t2 is the executing time for the code blocks.
t1 = measure { sleep(1) }

t2 = measure do
  sleep(2)
end
6
Houcheng

答えの多くは、Time.now。ただし、Time.now 変えられる。システムクロックはドリフトする可能性があり、システムの管理者またはNTPによって修正される場合があります。そのため、Time.nowが前後にジャンプして、ベンチマークの結果が不正確になる可能性があります。

より良い解決策は、常に前進しているオペレーティングシステムの単調クロックを使用することです。 Ruby 2.1以降では、次の方法でこれにアクセスできます。

start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# code to time
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
diff = finish - start # gets time is seconds as a float

詳細を読むことができます こちら 。また、人気のあるRubyプロジェクト、Sidekiq、 単調時計 に切り替えたことがわかります。

5
Guy C

Ruby-profパッケージには、必要なものが含まれているはずです。タイミングを持つ巨大な呼び出しスタックを作成します。

http://Ruby-prof.rubyforge.org/

粒度が細かすぎる可能性があります。その場合、Benchmark.measureは良い方法かもしれません。

3
Cody Caughlan

wquist's answer の精神ではありますが、もう少し簡単に、以下のようにすることもできます。

start = Time.now
# code to time
Time.now - start
2
ADude2