2016-09-22 69 views
4

這是很醜陋:在Ruby中測量時間的慣用方法是什麼?

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

我嘗試這樣做:

elapsed = time do 
    result = do_something 
end 

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

這是更好的。但問題是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_methodmy_method的返回值,它返回一個枚舉器,以便它可以鏈接到其他方法。

作爲一個例子,我們假設你想總結一個數組的值直到遇到零。一種方法是構造一個枚舉器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 

我使用的beginensureend塊以確保$timings << [__method__, Time.now - extime]被執行時,方法返回過早。 sleep(0.5)當然僅用於說明目的。

讓我們試試吧。

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

$timings將包含的含有時刻碼所有方法的執行時間的歷史。

相關問題