测量和基准时间为Ruby方法(Measure and Benchmark Time for Ruby

2019-07-30 07:56发布

我怎么能衡量的方法,并在Ruby中这种方法的个别报表所花费的时间。 如果你看到下面的方法,我想衡量方法,并采取了数据库访问和Redis的访问时所花费的总时间。 我不希望每个语句之前写Benchmark.measure。 请问Ruby解释器为我们提供了这个产品的挂钩?

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

Answer 1:

你可以使用的Time对象。 ( 时间文档 )

例如,

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

diff = finish - start

diff将在几秒钟内,作为一个浮点数。

编辑: end被保留。



Answer 2:

最简单的方法:

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时间,系统时间,总的和实际经过的时间。

来源: 红宝石文档 。



Answer 3:

使用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: Not shown in output.

更多信息可以找到这里 。



Answer 4:

第二思想,定义与Ruby代码块的参数测量()函数可以帮助简化时间度量的代码:

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


Answer 5:

许多问题的答案建议使用的Time.now 。 但它是值得的知道Time.now可以改变。 系统时钟可以漂移,可能由系统管理员或通过NTP得到纠正。 因此,它是可能的Time.now跳向前或向后,让您的基准测试结果不准确。

一个更好的解决方案是使用操作系统的单调时钟,它总是向前发展。 红宝石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项目,Sidekiq,切换到了单调的时钟 。



Answer 6:

看看进入ruby-prof包,它应该有你所需要的。 这将创建一个巨大的定时调用堆栈。

http://ruby-prof.rubyforge.org/

这可能是过于详尽,在这种情况下,只是包裹更大部分在Benchmark.measure可能是一个很好的路要走。



Answer 7:

在精神wquist的答案 ,但稍微简单一些,你也可以做到这一点象下面这样:

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


文章来源: Measure and Benchmark Time for Ruby Methods