ruby - 能不能像函数式编程一样处理Ruby的方法,比如memoizing一个函数?

标签 ruby functional-programming memoization

我可以通过使用本地作用域和闭包来内存 Ruby 函数:

require "benchmark"

fib = ->(n) {
  return 0 if n < 0
  return 1 if n == 0
  return fib.(n-1) + fib.(n-2)
}

memoize = ->(f) {
  already_know = {}

  new_function = ->(n) {
    already_know[n] ||= f.(n)
    return already_know[n]
  }
  return new_function
}

fib = memoize.(fib)

puts Benchmark.measure { p fib.(42) }

运行时间为 0.000011 秒。如果没有 fib = memoize.(fib) 行,运行需要 259 秒。

但是你能用 Ruby 中的方法(而不是函数)做同样的事情吗?看起来 Python 方法更像是一个函数,因为您可以使用 Python 方法轻松地做到这一点,而 Ruby 的方法不太像一个函数 —— 可能是因为 Ruby 中的方法不是对象。但问题是,你能不能像上面代码中的memoize那样让一个方法变成memoized?

最佳答案

您可以为原始方法添加别名,并为原始实现添加一个简单的缓存。

class Fib
  def fib(n)
    case
    when n < 0  then 0
    when n == 0 then 1
    else fib(n-1) + fib(n-2)
    end
  end
end
puts Benchmark.measure { p Fib.new.fib(35) }

class Fib
  alias_method :fib_ori, :fib

  def fib(n)
    (@fib_cache ||= {})[n] ||= fib_ori(n)
  end
end  
puts Benchmark.measure { p Fib.new.fib(35) }

关于ruby - 能不能像函数式编程一样处理Ruby的方法,比如memoizing一个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34610055/

相关文章:

ruby-on-rails - 在每个场景之前在 cucumber 中运行 exec 'rake db:drop db:create db:migrate db:seed'

ruby - 在 sinatra 和 ruby​​ 中测试 Rack 超时

ruby-on-rails - 使用 Rails 和 nokogiri 解析 html

c++ - 使用回调来自定义类而不是子类化

haskell,IO Monoid 关联性被打破了吗?

sql-server - 我可以采取哪些措施来提高 SQL Server 中纯用户定义函数的性能?

ruby-on-rails - Rails 首先排序希腊字符

javascript - Folktale 的 future 是什么?

ruby-on-rails - 何时在 Ruby on Rails 中使用内存

algorithm - 如何创建一个 'n' 正整数数组,其中数组的子序列的总和都不相等?