Ruby方法的测量和基准时间

Pha*_*ani 76 ruby time benchmarking interpreter ruby-on-rails

如何在Ruby中测量方法和该方法中各个语句所花费的时间.如果您看到以下方法,我想测量方法所花费的总时间以及数据库访问和redis访问所用的时间.我不想在每个声明之前写Benchmark.measure.ruby解释器是否为我们提供了任何钩子?

def foo
# code to access database
# code to access redis. 
end
Run Code Online (Sandbox Code Playgroud)

wqu*_*ist 101

你可以使用这个Time对象.(时间文件)

例如,

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

diff = finish - start
Run Code Online (Sandbox Code Playgroud)

diff 将以秒为单位,作为浮点数.

编辑:end保留.

  • 只是一个小小的修正.`end`是保留的,所以使用其他变量名. (12认同)
  • “ Time.now”受系统时钟调整的影响,因此,最佳做法是改用“ Process.clock_gettime(Process :: CLOCK_MONOTONIC)”。但是对于粗略的计算这并不重要。https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/ (2认同)

小智 88

最简单的方法:

require 'benchmark'

def foo
 time = Benchmark.measure {
  code to test
 }
 puts time.real #or save it to logs
end
Run Code Online (Sandbox Code Playgroud)

样本输出:

2.2.3 :001 > foo
  5.230000   0.020000   5.250000 (  5.274806)
Run Code Online (Sandbox Code Playgroud)

值包括:cpu时间,系统时间,总时间和实际经过时间.

资料来源:ruby docs.

  • 如果你只是想要实时的话,你也可以做"Benchmark.realtime {block}" (34认同)
  • 你知道的是:时间单位是*秒*. (5认同)

Jos*_*ter 27

使用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
Run Code Online (Sandbox Code Playgroud)

这将输出如下内容:

                        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.
Run Code Online (Sandbox Code Playgroud)

更多信息可以在这里找到.

  • 我刚刚回到我自己的答案,并且(再次)对 Benchmark 处理这个问题的方式印象深刻。喜欢红宝石。 (3认同)
  • 这应该是首选答案:因为从 Ruby 2.2 开始,`Benchmark` 类使用单调时钟,如其他答案中所述。例如,请参阅以下源代码,并在第 286 行查找“def measure”:https://github.com/ruby/ruby/blob/ruby_2_2/lib/benchmark.rb (3认同)

Hou*_*eng 7

第二个想法,用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
Run Code Online (Sandbox Code Playgroud)


Guy*_*y C 7

许多答案都建议使用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
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读更多详细信息。您还可以看到流行的Ruby项目Sidekiq转换为单调时钟