在 Ruby 中测量时间的惯用方法是什么?
What is an idiomatic way to measure time in 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
的好方法?
你的想法是正确的,但为了避免范围问题,请这样做:
result = nil
elapsed = time do
result = do_something
end
一个真正惯用的方法是使用标准库。 :)
require 'benchmark'
result = nil
elapsed = Benchmark.realtime do
result = do_something
end
我喜欢你构建 time
方法的方式。我没有改进的建议,但我会就一个相关问题说几句话。假设您希望测量执行方法所花费的时间。有时您可能可以写一些简单的东西,例如:
require 'time'
t = Time.now
rv = my_method(*args)
et = t.Time.now - t
其他时候不方便。例如,假设您正在构造一个数组,其元素是 my_method
的 return 值或 my_method
return 枚举器,以便它可以链接到其他方法。
例如,假设您想要对数组的值求和,直到遇到零为止。一种方法是构造一个枚举器 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
我使用了 begin
、ensure
、end
块来确保 $timings << [__method__, Time.now - extime]
在方法 return 过早执行时执行。 sleep(0.5)
当然只是为了说明目的。
我们来试试吧。
$timings = []
arr = [1,7,0,3,4]
arr.stop_at_zero.reduce(:+)
#=> 8
$timings
#=> [[:stop_at_zero, 1.505672]]
$timings
将包含包含计时代码的所有方法的执行时间的历史记录。
这很丑陋:
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
的好方法?
你的想法是正确的,但为了避免范围问题,请这样做:
result = nil
elapsed = time do
result = do_something
end
一个真正惯用的方法是使用标准库。 :)
require 'benchmark'
result = nil
elapsed = Benchmark.realtime do
result = do_something
end
我喜欢你构建 time
方法的方式。我没有改进的建议,但我会就一个相关问题说几句话。假设您希望测量执行方法所花费的时间。有时您可能可以写一些简单的东西,例如:
require 'time'
t = Time.now
rv = my_method(*args)
et = t.Time.now - t
其他时候不方便。例如,假设您正在构造一个数组,其元素是 my_method
的 return 值或 my_method
return 枚举器,以便它可以链接到其他方法。
例如,假设您想要对数组的值求和,直到遇到零为止。一种方法是构造一个枚举器 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
我使用了 begin
、ensure
、end
块来确保 $timings << [__method__, Time.now - extime]
在方法 return 过早执行时执行。 sleep(0.5)
当然只是为了说明目的。
我们来试试吧。
$timings = []
arr = [1,7,0,3,4]
arr.stop_at_zero.reduce(:+)
#=> 8
$timings
#=> [[:stop_at_zero, 1.505672]]
$timings
将包含包含计时代码的所有方法的执行时间的历史记录。