4

如果你是一名 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

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

4

1 回答 1

5

MRI 1.8.7 中的基准产生:

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

在 MRI 1.9.0 中:

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

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

这是哈希块的基准:

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
于 2011-02-27T00:57:27.527 回答