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

时间:2010-02-18 14:42:07

标签: ruby timer

我希望弄清楚特定功能使用了多少毫秒。所以我看起来很高,但是找不到以毫秒精度在Ruby中获取时间的方法。

你是怎么做到的?在大多数编程语言中,它就像

start = now.milliseconds
myfunction()
end = now.milliseconds
time = end - start

10 个答案:

答案 0 :(得分:81)

您可以使用ruby的Time课程。例如:

t1 = Time.now
# processing...
t2 = Time.now
delta = t2 - t1 # in seconds

现在,delta是一个float对象,您可以获得与该类一样的结果。

答案 1 :(得分:54)

您还可以使用内置的Benchmark.measure功能:

require "benchmark"
puts(Benchmark.measure { sleep 0.5 })

打印:

0.000000   0.000000   0.000000 (  0.501134)

答案 2 :(得分:15)

使用Time.now(以挂钟时间为单位)作为基线会产生一些问题,可能会导致意外行为。这是因为挂钟时间可能会发生变化,例如插入的闰秒或time slewing,以便将当地时间调整为参考时间。

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

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

在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

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

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

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

答案 3 :(得分:13)

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

def time
  now = Time.now.to_f
  yield
  endd = Time.now.to_f
  endd - now
end

请注意,使用Time.now.to_f(与to_i不同)不会截断为秒。

答案 4 :(得分:1)

使用Time.now.to_f

答案 5 :(得分:1)

absolute_time gem是Benchmark的直接替代品,但使用原生指令要准确得多。

答案 6 :(得分:0)

使用Time.now.to_i返回1970/01/01传递的第二个。了解这一点,你可以做到

date1 = Time.now.to_f
date2 = Time.now.to_f
diff = date2 - date1

通过这种方式,您将在第二个幅度上有差异。如果您想要毫秒,只需添加代码

即可
diff = diff * 1000

答案 7 :(得分:0)

如果您使用

date = Time.now.to_i

你在几秒钟内获得时间,这远非准确,特别是如果你计算的是很少的代码块。

答案 8 :(得分:0)

我有一个可以分析你的ruby方法(实例或类)的gem - https://github.com/igorkasyanchuk/benchmark_methods

不再有这样的代码:

.css()

现在你可以做到:

<!DOCTYPE html>
<html>

<head>
  <style>
    div.divx {
      width: 50px;
      height: 50px;
      background-color: black;
      position: absolute;
      left: 15px;
      top: 15px;
      z-index: -1;
      transition: transform 500ms;
    }
  </style>
</head>
<body>
  <div class="divx"></div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js">
  </script>
  <script>
    $(document).ready(function() {
      var i = 0, a, yy, aa;
      $(window).keydown(function(e) {
        if (e.which == 39) { //39 is right button
          i += 5;
          a = i + 'px';
          yy = 'translateX(' + a + ')';
          aa = "transform," + yy;
          $(".divx").css("transform", yy);
        }
      })
    })
  </script>
</body>

</html>

然后调用你的方法

t = Time.now
user.calculate_report
puts Time.now - t

答案 9 :(得分:0)

我们还可以创建简单的函数来记录任何代码块:

def log_time
  start_at = Time.now

  yield if block_given?

  execution_time = (Time.now - start_at).round(2)
  puts "Execution time: #{execution_time}s"
end

log_time { sleep(2.545) } # Execution time: 2.55s