Ruby是否会缓存将评估相同结果的方法的结果?

时间:2016-01-18 21:47:25

标签: ruby-on-rails ruby caching

Ruby是否会缓存方法的结果,以便在调用两次时不需要对其进行两次评估?

我在Rails中工作,例如,我可以执行以下操作,将传递的参数的结果存储到Rails控制器中,如下所示:

def foo_bar_method
  case param[:foobar]
  when 'foo' then 'bar'
  when 'bar' then 'baz'
  else 'barbaz'
end

result = foo_bar_method
puts result
puts result

这样我只评估foo_bar_method一次。 Ruby是否缓存了此方法的结果(或Rails是否这样做)?使用上面显示的代码是否更快,或者以下代码是否会产生相同的性能?

def foo_bar_method
  case param[:foobar]
  when 'foo' then 'bar'
  when 'bar' then 'baz'
  else 'barbaz'
end

puts foo_bar_method
puts foo_bar_method

2 个答案:

答案 0 :(得分:1)

Ruby不会缓存方法的结果。如果您想自己动手,可以自己添加备忘录。有很多方法可以做到这一点和几个宝石。只取决于你需要什么(即参数处理等)

https://en.wikipedia.org/wiki/Memoization

答案 1 :(得分:1)

Ruby不会缓存方法结果,因为几乎没有任何ruby函数可以被称为纯函数,并且由于ruby是动态的,编译器无法判断值是否发生变化。例如这个函数:

def four
  2 + 2
end

似乎在时间上是不变的。好吧,如果你那样做,那就不是了。

class Fixnum
  def +(other)
    self * other - 3
  end
end  

嗯,显然这样做可能是你能做的最糟糕的事情,但事实是你可以做到。

在您的两个示例中,没有可衡量的性能提升,但在许多情况下,它是编写代码的标准方法(执行一次并存储到变量)。

当您确定要处理的函数总是会产生相同的结果时,可以使用如下的实例变量来缓存它:

def foo_bar_method
  @foo_bar_method ||= 
    case param[:foobar]
      when 'foo' then 'bar'
      when 'bar' then 'baz'
      else 'barbaz'
    end
end

假设这是控制器中的一个方法,可以安全地假设这个值在控制器生命周期中不会改变(因为每个请求使用不同的控制器实例),因此缓存可能会有一些意义,特别是对于更重的计算。 / p>