如何在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时间、系统时间、总计和真实经过的时间。
来源:Ruby文档。
Benchmark.realtime { block }
。 - jmccureTime
对象。(时间文档)例如,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
将会作为浮点数以秒为单位显示。
end
是保留字,所以请使用其他变量名。 - Jason KimTime.now
的值会受到系统时钟调整的影响,因此最好使用 Process.clock_gettime(Process::CLOCK_MONOTONIC)
。但是对于粗略计算来说,这并不重要。https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/ - Patrick Brinich-LangloisBenchmark
的报告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.
更多信息可以在这里找到。
Benchmark
类使用单调时钟,正如其他答案中所讨论的那样。请参阅以下源代码,并查找第286行的“def measure”:https://github.com/ruby/ruby/blob/ruby_2_2/lib/benchmark.rb - Purplejacket许多答案建议使用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
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
new Date()
的东西,但我记不清正确的语法了。不过,你可以在谷歌上找到相关的信息。 - reagan