我想弄清楚一个特定函数使用了多少毫秒。因此,我看上去高低不一,但找不到找到以毫秒为单位精度的Ruby时间的方法。
你怎么做到这一点?在大多数编程语言中,它就像
start = now.milliseconds
myfunction()
end = now.milliseconds
time = end - start
Answers:
您还可以使用内置的Benchmark.measure函数:
require "benchmark"
puts(Benchmark.measure { sleep 0.5 })
印刷品:
0.000000 0.000000 0.000000 ( 0.501134)
0.000000
)是什么?更新:在文档中查找它,它是用户CPU时间,系统CPU时间以及这两者的总和。
Benchmark.bm
。有时会花时间在哪里很有用。在这里,您可以看到该区块正处于空转状态(总计0,真实值0.5)
Benchmark.realtime
返回单个可理解的浮点数的:)
使用Time.now
(返回挂钟时间)作为基准线有两个问题,这些问题可能导致意外行为。这是由以下事实时钟时间是受像插入闰秒或变化而引起时间回转来调整本地时间与参考时间。
如果在测量过程中插入了例如a秒,它将be秒。同样,根据本地系统条件,您可能必须处理夏时制,运行时钟的速度更快或更慢,或者时钟甚至跳回到时间上,导致持续时间为负数,以及许多其他问题。
解决此问题的方法是使用不同的时钟时间:单调时钟。这种类型的时钟与挂钟具有不同的属性。它单调递增,即永不回退并以恒定速率增加。这样一来,它就不代表墙上的时钟(即您从墙上的时钟读取的时间),而是可以与以后的时间戳进行比较以获得不同的时间戳。
在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
方法以小数秒的浮点数形式返回时间戳。返回的实际数字没有定义的含义(您应该依靠)。但是,您可以确保下一个调用将返回更大的数字,并且通过比较这些值,您可以获得实时差。
这些属性使该方法成为测量时差的主要候选方法,而不会在最小的机会内看到程序失败(例如,在除夕夜午夜插入另一个leap秒)。
Process::CLOCK_MONOTONIC
此处使用的常数在所有现代Linux,BSD和macOS系统以及Windows的Linux子系统上均可用。但是,它尚不适用于“原始” Windows系统。在此,您可以使用GetTickCount64
系统调用,而不是Process.clock_gettime
在Windows(> = 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
是一个关键字。
end_time
或做某事,不要只是拼错单词,那简直就是地狱
该absolute_time
宝石是一个下拉更换为基准,但使用原生指令要准确得多。
我们还可以创建简单的函数来记录任何代码块:
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
使用Time.now.to_i
return从1970/01/01开始传递的第二个。知道这一点你可以做
date1 = Time.now.to_f
date2 = Time.now.to_f
diff = date2 - date1
这样,您将在第二幅度上有所不同。如果需要毫秒,只需将其添加到代码中
diff = diff * 1000
.to_i
给出一个整数,并将截断毫秒。如果您将其更改为.to_f
我有一个可以描述您的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