如何在 Ruby 中测量一个方法和该方法中的各个语句所花费的时间。如果您看到以下方法,我想测量该方法所花费的总时间以及数据库访问和 redis 访问所花费的时间。我不想在每条语句之前都写 Benchmark.measure。ruby 解释器是否为我们提供了执行此操作的任何钩子?
def foo
# code to access database
# code to access redis.
end
如何在 Ruby 中测量一个方法和该方法中的各个语句所花费的时间。如果您看到以下方法,我想测量该方法所花费的总时间以及数据库访问和 redis 访问所花费的时间。我不想在每条语句之前都写 Benchmark.measure。ruby 解释器是否为我们提供了执行此操作的任何钩子?
def foo
# code to access database
# code to access redis.
end
最简单的方法:
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 时间、系统时间、总和实际经过的时间。
来源:红宝石文档。
您可以使用该Time
对象。(时间文档)
例如,
start = Time.now
# => 2022-02-07 13:55:06.82975 +0100
# code to time
finish = Time.now
# => 2022-02-07 13:55:09.163182 +0100
diff = finish - start
# => 2.333432
diff
以秒为单位,作为浮点数。
Benchmark
报告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: This is not shown in output.
更多信息可以在这里找到。
许多答案建议使用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 代码块参数定义measure()函数可以帮助简化时间测量代码:
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
本着wquist's answer的精神,但更简单一点,您也可以像下面这样:
start = Time.now
# code to time
Time.now - start