6

由于我目前正在进行一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序的情况下测量用户时间或系统时间time

使用Time该类仅显示挂钟时间,而不是系统和用户时间,但是我正在寻找具有相同灵活性的解决方案,例如

time = TimeUtility.now
# some code
user, system, real = TimeUtility.now - time

原因是我不喜欢Benchmark,因为它不能只返回数字(编辑:我错了 - 它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX 系统的time实用程序也应该解决我的问题,但我想知道是否已经在 Ruby 中实现了某种包装器,所以我不需要自己进行这些系统调用。

非常感谢!

4

3 回答 3

9

我重新阅读了 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)
于 2011-06-17T05:56:40.930 回答
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]

请参阅timesLinux 上的底层调用。

这是一个非常糟糕的包装器,它支持-

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

应该给你一些想法,让它在你的环境中很好地工作。

于 2011-06-17T05:42:34.750 回答
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
于 2015-10-13T08:51:36.143 回答