如何在Ruby中以毫秒为单位计算操作?

Ear*_*rlz 74 ruby timer

我想知道一个特定函数使用了多少毫秒.所以我看起来很高,但是找不到以毫秒精度在Ruby中获取时间的方法.

你怎么做到这一点?在大多数编程语言中它只是像

start = now.milliseconds
myfunction()
end = now.milliseconds
time = end - start
Run Code Online (Sandbox Code Playgroud)

ezp*_*zpz 86

你可以使用ruby的Time类.例如:

t1 = Time.now
# processing...
t2 = Time.now
delta = t2 - t1 # in seconds
Run Code Online (Sandbox Code Playgroud)

现在,delta是一个float对象,你可以得到一个像课程一样的结果.

  • 这是一个简单的解决方案,但更好的是 Process.clock_gettime 的答案。见 https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/ (2认同)

Sim*_*tsa 55

您还可以使用内置的Benchmark.measure函数:

require "benchmark"
puts(Benchmark.measure { sleep 0.5 })
Run Code Online (Sandbox Code Playgroud)

打印:

0.000000   0.000000   0.000000 (  0.501134)
Run Code Online (Sandbox Code Playgroud)

  • 或者有一个`Benchmark.realtime`返回一个可理解的浮点数:) (12认同)

Hol*_*ust 18

使用Time.now(返回挂钟时间)作为基线有几个问题可能导致意外行为.这是因为挂钟时间可能会发生变化,例如插入的闰秒或时间转换以将当地时间调整为参考时间.

如果在测量期间插入例如闰秒,则它将关闭一秒钟.同样,根据当地系统条件,您可能需要处理夏令时,更快或更慢的时钟运行,或时钟甚至跳回时间,导致持续时间不足以及许多其他问题.

这个问题的解决方案是使用不同的时钟时间:单调时钟.这种类型的时钟具有与挂钟不同的属性.它会单调递增,即永不返回并以恒定速率增加.这样,它不代表挂钟(即您从墙上的时钟读取的时间),而是一个时间戳,您可以将其与后来的时间戳进行比较以获得差异.

在Ruby中,您可以使用以下类似的时间戳Process.clock_gettime(Process::CLOCK_MONOTONIC):

t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# => 63988.576809828

sleep 1.5 # do some work

t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# => 63990.08359163

delta = t2 - t1
# => 1.5067818019961123
delta_in_milliseconds = delta * 1000
# => 1506.7818019961123
Run Code Online (Sandbox Code Playgroud)

Process.clock_gettime方法返回一个带有小数秒的浮点数的时间戳.返回的实际数字没有明确的含义(您应该依赖).但是,您可以确定下一个调用将返回一个更大的数字,通过比较这些值,您可以获得实时差异.

这些属性使得该方法成为测量时间差异的主要候选者,而不会在最不合适的时间看到您的程序失败(例如,在新年前夜的午夜,当插入另一个闰秒时).

Process::CLOCK_MONOTONIC这里使用的常量可用于所有现代Linux,BSD和macOS系统以及Linux子系统Windows.(据我所知)尚未用于"原始"Windows系统.在那里,您可以使用GetTickCount系统调用而不是Process.clock_gettime在Windows上以毫秒粒度返回计时器值.

  • 这是唯一应该接受的答案,更不用说接受了。 (2认同)

sep*_*p2k 13

您应该查看基准模块以执行基准测试.但是,作为一种快速而肮脏的计时方法,您可以使用以下内容:

def time
  now = Time.now.to_f
  yield
  endd = Time.now.to_f
  endd - now
end
Run Code Online (Sandbox Code Playgroud)

请注意Time.now.to_f,与to_i不同,它的使用不会截断为秒.

  • 在这里浮动的时间是不必要的. (6认同)