如何查看哪种方法运行得更快

时间:2015-03-10 12:46:40

标签: ruby

如何确定哪种方法运行得更快?很难在Ruby文档中阅读Benchmark并实际实现它。感谢

def count_between(list_of_integers, lower_bound, upper_bound)
  count = 0
  list_of_integers.each do |x|
    (x >= lower_bound && x <= upper_bound) ? count += 1 : next
  end
  count
end

def count_between(list_of_integers, lower_bound, upper_bound)
 count = 0
 list_of_integers.each do |x|
   count += 1 if x.between?(lower_bound, upper_bound) 
 end
 count
end

3 个答案:

答案 0 :(得分:5)

基准测试的问题在于,对于执行速度非常快的事情,您需要多次运行测试才能对结果充满信心。 Benchmark不会为您提供任何帮助 - 您最终会在report块内部进行循环并修改重复执行计数。

benchmark-myps gem为你做了一些。基本用法与stdlib版本几乎相同:

require 'benchmark/ips'

#define your methods and test data here.
Benchmark.ips do |x|
  x.report 'count between 1' do
    count_between_1(list_of_integers, lower_bound, upper_bound)
  end

  x.report 'count between 2' do
    count_between_2(list_of_integers, lower_bound, upper_bound)
  end
end

生成类似

的输出
 count between 1    143.377  (± 4.9%) i/s -    728.000 
 count between 2     64.489  (± 4.7%) i/s -    324.000 

这使得更容易看出结果是否显着。

答案 1 :(得分:1)

require 'benchmark'

def count_between_1(list_of_integers, lower_bound, upper_bound)
  count = 0
  list_of_integers.each do |x|
    (x >= lower_bound && x <= upper_bound) ? count += 1 : next
  end
  count
end

def count_between_2(list_of_integers, lower_bound, upper_bound)
  count = 0
  list_of_integers.each do |x|
    count += 1 if x.between?(lower_bound, upper_bound)
  end
  count
end

list_of_integers = (1..100_000).to_a
lower_bound = 5
upper_bound = 80_000

Benchmark.bm do |x|
  x.report do
    count_between_1(list_of_integers, lower_bound, upper_bound)
  end

  x.report do
    count_between_2(list_of_integers, lower_bound, upper_bound)
  end
end

结果:

     user     system      total        real
 0.010000   0.000000   0.010000 (  0.008910)
 0.010000   0.000000   0.010000 (  0.018098)

所以第一个变种要快得多。

答案 2 :(得分:1)

下面。

def count_between(list_of_integers, lower_bound, upper_bound)
    count = 0
    s = Benchmark.realtime do 
        list_of_integers.each do |x|
            count += 1 if x.between?(lower_bound, upper_bound) 
        end
    end
    puts "Method took #{"%.04f" % s} seconds to complete"
    count
end

Benchmark.realtime将为它所包含的块计时,并返回一个浮点数,表示执行代码块所需的秒数(在浮点数的精度和系统的精度范围内)时钟)。

其他方法(如Benchmark.report和Benchmark.measure)将分解用户,系统和实际执行时间,这对于调试代码段的速度比预期慢的原因非常有用。