Ruby 中的不同记忆技术

发布于 2024-10-19 09:40:15 字数 479 浏览 6 评论 0原文

如果您是 Ruby 程序员,那么您可能遇到过哈希块记忆模式。作为一个简单的例子,我向您展示斐波那契序列的记忆版本:

fib_hash = Hash.new do |h,i|
  h[i] = h[i-1] + h[i-2]
end
# establish the base cases
fib_hash[1] = 1; fib_hash[2] = 1

当然,这不是创建斐波那契序列的记忆版本的唯一方法。您还可以执行以下操作:

@cache = {}; @cache[1] = 1; @cache[2] = 1
def memo_fib(n)
  @cache[n] ||= (memo_fib(n-1) + memo_fib(n-2))
end

希望您看到哈希块记忆模式如何映射到第二个版本,这在许多其他语言中更为常见。我想知道这两个版本有什么区别吗?我无法摆脱哈希块版本更高效的感觉,但我无法真正证明原因。

If you are a ruby programmer then you might have come across the hash block memoization pattern. For a simple example I present you the memoized version of the Fibonacci sequence:

fib_hash = Hash.new do |h,i|
  h[i] = h[i-1] + h[i-2]
end
# establish the base cases
fib_hash[1] = 1; fib_hash[2] = 1

Of course this is not the only way to create a memoized version of the Fibonacci sequence. You could also do the following:

@cache = {}; @cache[1] = 1; @cache[2] = 1
def memo_fib(n)
  @cache[n] ||= (memo_fib(n-1) + memo_fib(n-2))
end

Hopefully you see how the hash block memoization pattern maps to the second version which is much more common in many other languages. What I would like to know is if there is any difference between the two versions? I can't shake the feeling that the hash block version is more efficient but I can't really justify why.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅忆流年 2024-10-26 09:40:15

MRI 1.8.7 中的基准测试结果为:

  • 哈希块:0.44 秒
  • 非哈希块:0.41 秒

在 MRI 1.9.0 中:

  • 哈希块:0.24 秒
  • 非哈希块:0.28 秒

基准测试是从 1 计算斐波那契数的 100 次迭代到 1000,在每次迭代开始时重置哈希或缓存。

这是哈希块的基准:

def reset_fib_hash                                                              
  @fib_hash = Hash.new do |h,i|
    h[i] = h[i-1] + h[i-2]
  end
  # establish the base cases                                                    
  @fib_hash[1] = 1; @fib_hash[2] = 1
end

start_time = Time.now
100.times do
  reset_fib_hash
  (1..1000).each do |i|
    @fib_hash[i]
  end
end
p Time.now - start_time

这是非哈希块的基准:

def reset_fib_hash
  @cache = {}; @cache[1] = 1; @cache[2] = 1
end

def memo_fib(n)
  @cache[n] ||= (memo_fib(n-1) + memo_fib(n-2))
end

start_time = Time.now
100.times do
  reset_fib_hash
  (1..1000).each do |i|
    memo_fib(i)
  end
end
p Time.now - start_time

A benchmark in MRI 1.8.7 yields:

  • Hash block: 0.44 seconds
  • Non hash block: 0.41 seconds

And in MRI 1.9.0:

  • Hash block: 0.24 seconds
  • Non hash block: 0.28 seconds

The benchmark is 100 iterations of computing the Fibonacci numbers from 1 through 1000, resetting the hash or cache at the start of each iteration.

Here's the benchmark for the hash block:

def reset_fib_hash                                                              
  @fib_hash = Hash.new do |h,i|
    h[i] = h[i-1] + h[i-2]
  end
  # establish the base cases                                                    
  @fib_hash[1] = 1; @fib_hash[2] = 1
end

start_time = Time.now
100.times do
  reset_fib_hash
  (1..1000).each do |i|
    @fib_hash[i]
  end
end
p Time.now - start_time

Here's the benchmark for the non hash block:

def reset_fib_hash
  @cache = {}; @cache[1] = 1; @cache[2] = 1
end

def memo_fib(n)
  @cache[n] ||= (memo_fib(n-1) + memo_fib(n-2))
end

start_time = Time.now
100.times do
  reset_fib_hash
  (1..1000).each do |i|
    memo_fib(i)
  end
end
p Time.now - start_time
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文