start = now.milliseconds
myfunction()
end = now.milliseconds
time = end - start
Time
类。例如:t1 = Time.now
# processing...
t2 = Time.now
delta = t2 - t1 # in seconds
现在,delta
是一个float
对象,您可以获取类提供的最细致的结果。你还可以使用内置的Benchmark.measure函数:
require "benchmark"
puts(Benchmark.measure { sleep 0.5 })
输出:
0.000000 0.000000 0.000000 ( 0.501134)
Benchmark.bm
,它们会被标记出来。有时候查看时间花费在哪里很有用。在这里,您可以看到该块只是空闲状态(总共0秒,实际0.5秒)。 - Simon PerepelitsaBenchmark.realtime
方法,它会返回一个易于理解的单精度浮点数 :) - Sergio Tulentsev使用Time.now
(返回挂钟时间)作为基准线存在一些问题,可能导致意外的行为。这是由于挂钟时间受到诸如插入闰秒或时间调整等更改的影响。
如果在测量过程中插入了闰秒,则会误差1秒。同样地,根据本地系统条件,您可能需要处理夏令时、运行速度较快或较慢的时钟,甚至时钟倒回时间,导致负持续时间和许多其他问题。
解决此问题的方法是使用不同类型的时钟:单调时钟。这种类型的时钟具有与挂钟不同的属性。它单调递增,即永远不会后退并以恒定速率增加。因此,它不代表挂钟(即从墙上的时钟读取的时间),而是可以与稍后的时间戳进行比较以获取差异的时间戳。
在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 系统上提供。在那里,您可以使用 GetTickCount64
系统调用代替 Process.clock_gettime
,它还返回窗口系统(≥ Windows Vista,Windows Server 2008)中毫秒为粒度的计时器值。
在 Ruby 中,您可以像这样调用此函数:
require 'fiddle'
# Get a reference to the function once
GetTickCount64 = Fiddle::Function.new(
Fiddle.dlopen('kernel32.dll')['GetTickCount64'],
[],
-Fiddle::TYPE_LONG_LONG # unsigned long long
)
timestamp = GetTickCount64.call / 1000.0
# => 63988.576809828
您应该查看基准测试模块以进行性能测试。然而,作为一个快速而简单的计时方法,您可以使用以下代码:
def time
now = Time.now.to_f
yield
endd = Time.now.to_f
endd - now
end
注意使用 Time.now.to_f
,与 to_i
不同的是,它不会截取到秒。
end
是一个关键字。 - sepp2kdef 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
使用 Time.now.to_f
absolute_time
gem是Benchmark的即插即用替代品,但使用本地指令使其更加准确。"我有一个宝石可以对你的 Ruby 方法(实例或类)进行分析 - https://github.com/igorkasyanchuk/benchmark_methods。
不再需要像这样的代码:
t = Time.now
user.calculate_report
puts Time.now - t
现在你可以做:
benchmark :calculate_report # in class
然后只需调用您的方法
user.calculate_report
使用Time.now.to_i
可以返回从1970年01月01日开始经过的秒数。有了这个信息,你就可以做...
date1 = Time.now.to_f
date2 = Time.now.to_f
diff = date2 - date1
使用这个方法,你将会得到秒级别的差异。如果你想要毫秒级别的结果,只需要在代码中添加即可。
diff = diff * 1000
.to_i
gives an integer and would truncate the milliseconds. This would work if you just changed it to .to_f
- Ryan Taylor如果你使用
date = Time.now.to_i
你正在获取以秒为单位的时间,这远非准确,特别是当你计时小代码块时。