ruby-on-rails - Ruby 是否缓存将评估为相同结果的方法的结果?

标签 ruby-on-rails ruby caching

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

我在 Rails 工作,例如,我可以执行以下操作,将传递到 Rails Controller 的参数的结果存储在一个变量中,如下所示:

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

最佳答案

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

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

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

关于ruby-on-rails - Ruby 是否缓存将评估为相同结果的方法的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34864651/

相关文章:

c - sprintf vs strcpy - 使用更多内存和快速复制还是几乎没有内存和慢速复制?

带参数的 Ruby DSL define_method

iOS - 禁用 Alamofire 缓存参数

mysql - 我想删除 "Mysql2::Error::ConnectionError (Unknown MySQL server host ' db' (0)) :"

ruby-on-rails - 在 Rails Controller 中处理所需参数的最佳方式?

ruby-on-rails - Ruby/Rails 如何在 DateTime 范围内迭代月份?

ruby-on-rails - 设计自定义登录表单

ruby-on-rails - 从像 http ://localhost:3000/user/adem-balka with Rails 5 这样的友好 url 获取参数

ruby - 循环遍历数组 ruby

java - 当共享 JDBC 缓存存储到位时,将 "numOwners"在 Infinispan 中设置为大于 1 是否有效?