Ruby 中具有多个参数的记忆函数
Memoizing functions with multiple parameters in Ruby
我想知道在 Ruby 中是否有更多 "Ruby-like" 方法来记忆具有多个参数的函数。这是我想出的一种方法,但不确定它是否是最好的方法:
@cache = {}
def area(length, width) #Just an example, caching is worthless for this simple function
key = [length.to_s, width.to_s].join(',')
if @cache[key]
puts 'cache hit!'
return @cache[key]
end
@cache[key] = length * width
end
puts area 5, 3
puts area 5, 3
puts area 4, 3
puts area 3, 4
puts area 4, 3
参数用逗号连接,然后用作存储在 @cache
变量中的键。
可以直接使用数组:
def area(length, width)
key = [length, width]
if @cache[key]
puts 'cache hit!'
return @cache[key]
end
@cache[key] = length * width
end
或使用嵌套哈希:
def area(length, width)
c = (@cache[length] ||= {})
if c[width]
puts 'cache hit!'
return c[width]
end
c[width] = length * width
end
当你不需要打印 Cache hit!
时,我会这样做:
def area(length, width)
@cache ||= {}
@cache["#{length},#{width}"] ||= length * width
end
或者如果您需要一些输出,但 Cache miss!
也可以:
def area(length, width)
@cache ||= {}
@cache.fetch("#{length},#{width}") do |key|
puts 'Cache miss!'
@cache[key] = length * width
end
end
如果你想接受更多的参数,你可能想使用这样的东西:
def area(*args)
@cache ||= {}
@cache[args] ||= args.inject(:*)
end
在 Ruby 2.7 及更高版本 中,位置参数和关键字参数被隔离,这对如何实现多参数记忆有影响。对于通用实现,我会做这样的事情:
def my_method(*args, **kwargs)
(@my_method_cache ||= {})[args.hash ^ kwargs.hash] ||= begin
(...)
end
end
用 my_method
完成的昂贵计算替换 (...)
。
我想知道在 Ruby 中是否有更多 "Ruby-like" 方法来记忆具有多个参数的函数。这是我想出的一种方法,但不确定它是否是最好的方法:
@cache = {}
def area(length, width) #Just an example, caching is worthless for this simple function
key = [length.to_s, width.to_s].join(',')
if @cache[key]
puts 'cache hit!'
return @cache[key]
end
@cache[key] = length * width
end
puts area 5, 3
puts area 5, 3
puts area 4, 3
puts area 3, 4
puts area 4, 3
参数用逗号连接,然后用作存储在 @cache
变量中的键。
可以直接使用数组:
def area(length, width)
key = [length, width]
if @cache[key]
puts 'cache hit!'
return @cache[key]
end
@cache[key] = length * width
end
或使用嵌套哈希:
def area(length, width)
c = (@cache[length] ||= {})
if c[width]
puts 'cache hit!'
return c[width]
end
c[width] = length * width
end
当你不需要打印 Cache hit!
时,我会这样做:
def area(length, width)
@cache ||= {}
@cache["#{length},#{width}"] ||= length * width
end
或者如果您需要一些输出,但 Cache miss!
也可以:
def area(length, width)
@cache ||= {}
@cache.fetch("#{length},#{width}") do |key|
puts 'Cache miss!'
@cache[key] = length * width
end
end
如果你想接受更多的参数,你可能想使用这样的东西:
def area(*args)
@cache ||= {}
@cache[args] ||= args.inject(:*)
end
在 Ruby 2.7 及更高版本 中,位置参数和关键字参数被隔离,这对如何实现多参数记忆有影响。对于通用实现,我会做这样的事情:
def my_method(*args, **kwargs)
(@my_method_cache ||= {})[args.hash ^ kwargs.hash] ||= begin
(...)
end
end
用 my_method
完成的昂贵计算替换 (...)
。