Ruby方法的度量和基准时间

tktrz96b  于 12个月前  发布在  Ruby
关注(0)|答案(6)|浏览(152)

如何测量Ruby中一个方法和该方法中的各个语句所花费的时间。如果你看到下面的方法,我想测量该方法所花费的总时间以及数据库访问和redis访问所花费的时间。我不想在每个语句之前编写Benchmark.measure。Ruby解释器是否提供了任何钩子来完成这一任务?

def foo
# code to access database
# code to access redis. 
end

字符串

ruyhziif

ruyhziif1#

最简单的方法:

require 'benchmark'

def foo
 time = Benchmark.measure do
  code to test
 end
 puts time.real #or save it to logs
end

字符串
示例输出:

2.2.3 :001 > foo
  5.230000   0.020000   5.250000 (  5.274806)


值为:CPU时间、系统时间、总运行时间和真实的运行时间。
来源:ruby docs

hfyxw5xn

hfyxw5xn2#

您可以使用Time对象。(Time Docs
比如说,

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将以秒为单位,作为浮点数。

eeq64g8w

eeq64g8w3#

使用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.

  • 更多信息可以在这里找到。*
wlsrxk51

wlsrxk514#

许多答案建议使用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

字符串
你可以阅读here的更多细节。你也可以看到流行的Ruby项目Sidekiq,切换到了monotonic clock

oxf4rvwz

oxf4rvwz5#

第二个想法是,使用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

字符串

yx2lnoni

yx2lnoni6#

按照wquist's answer的精神,但更简单一点,你也可以像下面这样做:

start = Time.now
# code to time
Time.now - start

字符串

相关问题