由于我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark
类或命令行实用程序time
的情况下测量用户时间或系统时间。< / p>
使用Time
类只显示挂钟时间,而不是系统和用户时间,但我正在寻找具有相同灵活性的解决方案,例如
time = TimeUtility.now
# some code
user, system, real = TimeUtility.now - time
原因是我不喜欢Benchmark
,因为它不能只返回数字(编辑:我错了 - 它可以。见下面的答案。)。当然,我可以解析输出,但这感觉不对。来自* NIX系统的time
实用程序也应该解决我的问题,但我想知道是否已经在Ruby中实现了某种包装器,所以我不需要自己进行这些系统调用。
非常感谢!
答案 0 :(得分:8)
我重新阅读了Benchmark文档,发现它有一个名为measure
的方法。这个方法完全符合我的要求:测量代码所需的时间并返回一个包含用户时间,系统时间,子系统时间等的对象。就像
require 'benchmark'
measurement = Benchmark.measure do
# your code goes here
end
在此过程中,我发现您可以将自定义行添加到Benchmark输出中。您可以使用它来获得两个方面的最佳效果(自定义时间测量和最后的良好输出),如下所示:
require 'benchmark'
measurements = []
10.times { measurements << Benchmark.measure { 1_000_000.times { a = "1" } } }
# measurements.sum or measurements.inject(0){...} does not work, since the
# array contains Benchmark instances, which cannot be coerced into Fixnum's
# Array#sum will work if you are using Rails
sum = measurements.inject(nil) { |sum, t| sum.nil? ? sum = t : sum += t }
avg = sum / measurements.size
# 7 is the width reserved for the description "sum:" and "avg:"
Benchmark.bm(7, "sum:", "avg:") do |b|
[sum, avg]
end
结果如下所示:
user system total real
sum: 2.700000 0.000000 2.700000 ( 2.706234)
avg: 0.270000 0.000000 0.270000 ( 0.270623)
答案 1 :(得分:2)
您可以使用Process::times
函数,该函数返回用户时间/系统时间。 (它不报告挂钟时间,你需要其他东西)。似乎是一个版本或操作系统依赖。
这是我在我的系统上报告的内容(linux,ruby 1.8.7):
$ irb
irb(main):001:0> t = Process.times
=> #<struct Struct::Tms utime=0.01, stime=0.0, cutime=0.0, cstime=0.0>
虽然文档显示了这一点,但是某些版本/实现可能只有前两个:
t = Process.times
[ t.utime, t.stime ] #=> [0.0, 0.02]
请参阅times
了解Linux上的基础调用。
这是一个非常糟糕的包装器,支持-
:
class SysTimes
attr_accessor :user, :system
def initialize
times = Process.times
@user = times.utime
@system = times.stime
end
def -(other)
diff = SysTimes.new
diff.user = @user - other.user
diff.system = @system - other.system
diff
end
end
应该给你一些想法,让它在你的环境中很好地运作。
答案 2 :(得分:0)
这个宝石可能会有所帮助: https://github.com/igorkasyanchuk/benchmark_methods
不再有这样的代码:
t = Time.now
user.calculate_report
puts Time.now - t
现在你可以做到:
benchmark :calculate_report # in class
然后调用你的方法
user.calculate_report