如何在Ruby中获得经过的时间(以毫秒为单位)?


98

如果我有一个Time物体来自:

Time.now

然后我用同一行实例化另一个对象,如何查看已经过了几毫秒?可以在接下来的几分钟甚至几小时内的同一分钟创建第二个对象。

Answers:


133

如前所述,您可以Time像处理数字(或浮点)值一样操作对象。这些操作导致可以轻松转换的第二分辨率。

例如:

def time_diff_milli(start, finish)
   (finish - start) * 1000.0
end

t1 = Time.now
# arbitrary elapsed time
t2 = Time.now

msecs = time_diff_milli t1, t2

您将需要决定是否将其截断。


2
添加一个to_i,并将其作为整数,例如:((finish-start)* 1000.0).to_i
Travis Reeder 2010年

finish.to_f - start.to_f
胆大的2014年

1
finish - start产生浮点;.to_f将是多余的。
ezpz

5
如果使用导轨或主动支撑,则可以使用#in_milliseconds方法执行相同的转换(t2 - t1).in_milliseconds
Nathan Hanna

58

您可以使用以下方法在上述解决方案中添加一些语法糖:

class Time
  def to_ms
    (self.to_f * 1000.0).to_i
  end
end

start_time = Time.now
sleep(3)
end_time = Time.now
elapsed_time = end_time.to_ms - start_time.to_ms  # => 3004

31

我认为答案选择不正确,该方法给出的是秒而不是毫秒。

t = Time.now.t­o_f
=> 1382471965.146

在这里,我假设浮点值是毫秒


1
选择的答案是正确的。使用加法或减法Time.now会将时间视为浮点值,小数点前为秒,小数点后为纳秒(尽管nsec可能不完全准确)。因此,将该值乘以将1000.0产生毫秒数。
dfherr

是的,但是仅给出“ Time.now”是不准确的,并且不能准确回答问题。
LowFieldTheory

12

为了获得以毫秒为单位的时间,最好添加.round(3),因此在某些情况下它将更加准确:

puts Time.now.to_f # => 1453402722.577573

(Time.now.to_f.round(3)*1000).to_i  # => 1453402722578

9

ezpz的答案几乎是完美的,但我希望我可以再添加一点。

Geo询问了时间(以毫秒为单位);这听起来像是整数,我不会绕过浮点地。因此,我的方法是:

irb(main):038:0> t8 = Time.now
=> Sun Nov 01 15:18:04 +0100 2009
irb(main):039:0> t9 = Time.now
=> Sun Nov 01 15:18:18 +0100 2009
irb(main):040:0> dif = t9 - t8
=> 13.940166
irb(main):041:0> (1000 * dif).to_i
=> 13940

乘以整数1000会完美保留分数,并且可能也会快一点。

如果要处理日期和时间,则可能需要使用DateTime类。这类似地工作,但是转换因子为24 * 3600 * 1000 = 86400000

我发现DateTime的strptimestrftime函数在解析和格式化日期/时间字符串(例如到/从日志)中非常有用。方便知道的是:

  • 这些函数的格式字符(%H,%M,%S等)几乎与任何Unix / Linux系统上的C函数相同;和

  • 还有其他一些:特别是%L可以毫秒!


很高兴知道!谢谢unknown:)
地理

1
无论如何,%L仅存在于Ruby 1.9中;)
拉法·德·卡斯特罗


6

Time.now.to_f可以为您提供帮助,但返回秒数。

通常,在使用基准测试时,我:

  • 将当前时间置于变量中;
  • 插入测试块;
  • 将当前时间放入变量中,减去先前的当前时间值;

这是一个非常简单的过程,所以我不确定您是否真的在问这个...


6

%L 给出红宝石的毫秒数

require 'time'
puts Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L")

要么

puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")

将为您提供当前时间戳(以毫秒为单位)。


这里没有说如何获得经过时间。
罗伯特

4

答案是这样的:

t_start = Time.now
# time-consuming operation
t_end = Time.now

milliseconds = (t_start - t_end) * 1000.0

但是,该Time.now方法存在不准确的风险。我发现了Luca Guidi的这篇文章:

https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/

系统时钟一直在浮动,并且不会向前移动。如果您基于它来计算经过时间,则很可能会遇到计算错误甚至中断

因此,建议改为使用Process.clock_gettime。就像是:

def measure_time
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  yield
  end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  elapsed_time = end_time - start_time
  elapsed_time.round(3)
end

例:

elapsed = measure_time do
    # your time-consuming task here:
    sleep 2.2321
end

=> 2.232

3

尝试从第二个减去第一个Time.now。像这样:

a = Time.now
sleep(3)
puts Time.now - a # about 3.0

这为您提供了两次之间的秒数(以毫秒为单位)的浮点数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.