2016-09-22 10 views
4

これはかなり醜いです:これは良いですRubyで時間を測定する慣習的な方法は何ですか?

elapsed = time do 
    result = do_something 
end 

def time 
    t = Time.now 
    yield 
    Time.now - t 
end 

t = Time.now 
result = do_something 
elapsed = Time.now - t 

私はこれを試してみました。しかし、問題はブロックが終了した後にresultが範囲外になることです。

タイミングの良い方法はありますか?または、resultを使用する良い方法はありますか?

答えて

4

を本当に慣用的な方法は、標準ライブラリを使用することです。 :)

require 'benchmark' 

result = nil 
elapsed = Benchmark.realtime do 
    result = do_something 
end 
2

あなたはここに正しい考えを持っているが、スコープの問題を避けるために、この操作を行います。

result = nil 
elapsed = time do 
    result = do_something 
end 
2

私はあなたのtimeメソッドを構築した方法が好きです。改善の提案はありませんが、私は関連する問題について少し言います。メソッドの実行に費やされた時間を測定したいとします。場合によっては、次のような単純なものを書くことができるかもしれません。

require 'time' 

t = Time.now 
rv = my_method(*args) 
et = t.Time.now - t 

他の時は便利ではありません。たとえば、戻り値がmy_methodまたはmy_methodの要素を持つ配列を構築していたら、列挙子が返され、他のメソッドに連結される可能性があります。

例として、ゼロに遭遇するまで配列の値を合計したいとしましょう。これを行う1つの方法は、ゼロに遭遇するまで受信者から値を生成する列挙子stop_at_zeroを構築し、次に停止する(すなわち、StopIteration例外を発生させる)。私たちは、その後、書くことができます:

arr.stop_at_zero.reduce(:+) 

我々は次のように我々はそれを構築することができstop_at_zeroの実行に費やされているどのくらいの時間を知りたい場合。

class Array 
    def stop_at_zero 
    extime = Time.now 
    Enumerator.new do |y| 
     begin 
     each do |n| 
      sleep(0.5) 
      return y if n.zero? 
      y << n 
     end 
     ensure 
     $timings << [__method__, Time.now - extime] 
     end 
    end 
    end 
end 

は、私はこの方法が途中で返したときに実行される $timings << [__method__, Time.now - extime]を確認するために beginensureendブロックを使用しました。 sleep(0.5)はもちろん説明のためだけのものです。

お試しください。

$timings = [] 
arr = [1,7,0,3,4] 
arr.stop_at_zero.reduce(:+) 
    #=> 8 
$timings 
    #=> [[:stop_at_zero, 1.505672]] 

$timingsタイミングコードが含まれているすべてのメソッドの実行時間の履歴が含まれています。

関連する問題