Ruby中的基准测试方法

use*_*140 3 ruby benchmarking

我试图像这样对一组计算进行基准测试 -

def benchmark(func, index, array)
    start = Time.now
    func(index, array)
    start - Time.now #returns time taken to perform func
end

def func1(index, array)
    #perform computations based on index and array
end 

def func2(index, array)
    #more computations....
end

benchmark(func1, index1, array1)
benchmark(func1, index2, array2)
Run Code Online (Sandbox Code Playgroud)

现在我想知道如何实现这一目标.我试过这个例子,但是吐了出来

`func1': wrong number of arguments (0 for 2) (ArgumentError)
Run Code Online (Sandbox Code Playgroud)

如果我尝试 -

benchmark(func1(index1, array1), index1, array1)
Run Code Online (Sandbox Code Playgroud)

吐出来......

undefined method `func' for main:Object (NoMethodError)
Run Code Online (Sandbox Code Playgroud)

我看到了一个类似的问题,但它是为了python.使用参数将函数传递给Python中的另一个函数? 有人可以帮忙吗?谢谢.

Aje*_*i32 7

在Ruby中,可以在方法名称后面调用方法而不包括空括号,如下所示:

def func1
  puts "Hello!"
end

func1 # Calls func1 and prints "Hello!"
Run Code Online (Sandbox Code Playgroud)

因此,当你编写时benchmark(func1, index1, array1),你实际上是func1在没有参数的情况下调用并将结果传递给benchmark,而不是func1按预期传递给基准函数.为了func1作为对象传递,您可以使用该method方法获取函数的包装器对象,如下所示:

def func1
  puts "Hello!"
end

m = method(:func1) # Returns a Method object for func1
m.call(param1, param2)
Run Code Online (Sandbox Code Playgroud)

大多数时候,这不是你真正想做的事情.Ruby支持一个名为blocks的结构,它更适合于此目的.您可能已经熟悉eachRuby用于循环遍历数组的迭代器中的块.以下是为您的用例使用块的样子:

def benchmark
  start = Time.now
  yield
  Time.now - start # Returns time taken to perform func
end

# Or alternately:
# def benchmark(&block)
#   start = Time.now
#   block.call
#   Time.now - start # Returns time taken to perform func
# end

def func1(index, array)
    # Perform computations based on index and array
end 

def func2(index, array)
    # More computations....
end

benchmark { func1(index1, array1) }
benchmark { func1(index1, array2) }
Run Code Online (Sandbox Code Playgroud)

实际上,Ruby有一个用于基准测试的标准库,名为Benchmark,它使用块,可能已经完全符合您的要求.

用法:

require 'benchmark'

n = 5000000
Benchmark.bm do |x|
  x.report { for i in 1..n; a = "1"; end }
  x.report { n.times do   ; a = "1"; end }
  x.report { 1.upto(n) do ; a = "1"; end }
end
Run Code Online (Sandbox Code Playgroud)

结果:

    user     system      total        real
1.010000   0.000000   1.010000 (  1.014479)
1.000000   0.000000   1.000000 (  0.998261)
0.980000   0.000000   0.980000 (  0.981335)
Run Code Online (Sandbox Code Playgroud)