我曾被告知使用fetch(:key) { nil }
代替fetch(:key, nil)
,因为即使nil
占用了一些内存,只有在找不到密钥时才最好对其进行评估。
我不确定这是否正确。这个块也不会占用一些内存吗?有没有办法检查这个?
答案 0 :(得分:5)
这是一些你不应该担心的微观优化。差异更具语义性。如果找不到:key
,
fetch(:key, nil)
将返回值nil
。
fetch(:key) {nil}
将评估该块并返回该值,但如果您使用nil
hash[:key]
将是返回值
对于这种微不足道的案例,我建议使用fetch(:key, nil)
。
当且仅当找不到:key
时,传递一个块才能计算更复杂的值,例如:
fetch(:key) { read(url).parse.get('value') }
如果您真的想知道哪一个更有效,您可以尝试对其进行基准测试,但如果块调用没有优化,我非常肯定该块会慢一些。
答案 1 :(得分:2)
出于好奇:
require 'benchmark'
N = 1_000_000
def benchmark(hsh)
Benchmark.bm(23) do |x|
x.report('hsh[:key]') { N.times { hsh[:key] } }
x.report('hsh.fetch(:key, nil)') { N.times { hsh.fetch(:key, nil ) } }
x.report('hsh.fetch(:key) { nil }') { N.times { hsh.fetch(:key) { nil } } }
end
end
puts
puts ' Missing key '.center(69, '-')
benchmark({})
puts
puts ' Existing key '.center(69, '-')
benchmark({ key: 1 })
输出:
---------------------------- Missing key ----------------------------
user system total real
hsh[:key] 0.067592 0.000116 0.067708 ( 0.067754)
hsh.fetch(:key, nil) 0.075391 0.000078 0.075469 ( 0.075515)
hsh.fetch(:key) { nil } 0.132427 0.000238 0.132665 ( 0.132850)
--------------------------- Existing key ----------------------------
user system total real
hsh[:key] 0.058410 0.000007 0.058417 ( 0.058422)
hsh.fetch(:key, nil) 0.072805 0.000007 0.072812 ( 0.072816)
hsh.fetch(:key) { nil } 0.076052 0.000326 0.076378 ( 0.076835)