Bug #10003
closedHash#fetch performance issue
Description
It looks like there is a performance issue with Hash#fetch compared to Hash#[]. I found this issue via this gist: https://gist.github.com/jonleighton/3552829. I could not find it reported anywhere on the tracker, forgive me if this is a known issue:
require 'benchmark/ips'
h = { foo: :bar }
Benchmark.ips do |r|
r.report('#[]') { h[:foo] }
r.report('#fetch') { h.fetch(:foo) }
end
Calculating -------------------------------------
#[] 124893 i/100ms
#fetch 121729 i/100ms
-------------------------------------------------
#[] 6917857.4 (±20.4%) i/s - 32472180 in 5.008832s
#fetch 4570251.5 (±18.8%) i/s - 22032949 in 5.015712s
This is in Ruby 2.1.2
Updated by jeremyevans0 (Jeremy Evans) almost 10 years ago
I believe this is expected since the Hash#[] call is optimized to call rb_hash_aref (see opt_aref in insns.def), where the Hash#fetch call goes through normal method dispatch. Array#[] calls are similarly optimized to call rb_ary_entry.
Updated by normalperson (Eric Wong) almost 10 years ago
Jeremy is correct, Hash#[] (and Array#[]) have optimized dispatch.
I hardly see Hash#fetch used anywhere, and optimizing dispatch for
uncommon cases hurts performance of common cases.
P.S. even if Hash#fetch were optimized, it would still be slower
because it has optional args to parse.
Updated by jeremyevans0 (Jeremy Evans) almost 5 years ago
- Status changed from Open to Closed