From d6e1ac0ef58931479e5c89478992a78c0271acd9 Mon Sep 17 00:00:00 2001 From: Dennis Ideler Date: Sun, 20 Mar 2016 11:40:54 +0000 Subject: [PATCH] :memo: Introduce Hash#dig and link to more info Closes #102 --- README.md | 36 ++++++++++++++++----------------- code/hash/dig-vs-[]-vs-fetch.rb | 14 ++++++------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 0b36cf7..b697f59 100644 --- a/README.md +++ b/README.md @@ -593,31 +593,29 @@ Comparison: ##### `Hash#dig` vs `Hash#[]` vs `Hash#fetch` [code](code/hash/dig-vs-[]-fetch.rb) +[Ruby 2.3 introduced `Hash#dig`](http://ruby-doc.org/core-2.3.0/Hash.html#method-i-dig) which is a readable +and performant option for retrieval from a nested hash, returning `nil` if an extraction step fails. +See [#102 (comment)](https://github.com/JuanitoFatas/fast-ruby/pull/102#issuecomment-198827506) for more info. + ``` $ ruby -v code/hash/dig-vs-\[\]-vs-fetch.rb ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15] -Warming up -------------------------------------- - Hash#dig 142.217k i/100ms - Hash#[] 153.313k i/100ms - Hash#[] || 145.380k i/100ms - Hash#[] && 121.401k i/100ms - Hash#fetch 137.236k i/100ms - Hash#fetch fallback 120.010k i/100ms + Calculating ------------------------------------- - Hash#dig 6.216M (± 6.2%) i/s - 31.003M - Hash#[] 6.676M (± 6.3%) i/s - 33.269M - Hash#[] || 6.160M (± 6.2%) i/s - 30.675M - Hash#[] && 3.096M (± 5.4%) i/s - 15.539M - Hash#fetch 4.425M (± 5.5%) i/s - 22.095M - Hash#fetch fallback 3.279M (± 5.3%) i/s - 16.441M + Hash#dig 5.719M (± 6.1%) i/s - 28.573M in 5.013997s + Hash#[] 6.066M (± 6.9%) i/s - 30.324M in 5.025614s + Hash#[] || 5.366M (± 6.5%) i/s - 26.933M in 5.041403s + Hash#[] && 2.782M (± 4.8%) i/s - 13.905M in 5.010328s + Hash#fetch 4.101M (± 6.1%) i/s - 20.531M in 5.024945s + Hash#fetch fallback 2.975M (± 5.5%) i/s - 14.972M in 5.048880s Comparison: - Hash#[]: 6676415.9 i/s - Hash#dig: 6215966.7 i/s - same-ish: difference falls within error - Hash#[] ||: 6160177.6 i/s - same-ish: difference falls within error - Hash#fetch: 4424551.0 i/s - 1.51x slower - Hash#fetch fallback: 3278599.3 i/s - 2.04x slower - Hash#[] &&: 3096090.4 i/s - 2.16x slower + Hash#[]: 6065791.0 i/s + Hash#dig: 5719290.9 i/s - same-ish: difference falls within error + Hash#[] ||: 5366226.5 i/s - same-ish: difference falls within error + Hash#fetch: 4101102.1 i/s - 1.48x slower + Hash#fetch fallback: 2974906.9 i/s - 2.04x slower + Hash#[] &&: 2781646.6 i/s - 2.18x slower ``` ##### `Hash[]` vs `Hash#dup` [code](code/hash/bracket-vs-dup.rb) diff --git a/code/hash/dig-vs-[]-vs-fetch.rb b/code/hash/dig-vs-[]-vs-fetch.rb index 87a7fa4..d296441 100644 --- a/code/hash/dig-vs-[]-vs-fetch.rb +++ b/code/hash/dig-vs-[]-vs-fetch.rb @@ -1,29 +1,29 @@ -require 'benchmark/ips' +require "benchmark/ips" h = { a: { b: { c: { d: { e: "foo" } } } } } Benchmark.ips do |x| - x.report 'Hash#dig' do + x.report "Hash#dig" do h.dig(:a, :b, :c, :d, :e) end - x.report 'Hash#[]' do + x.report "Hash#[]" do h[:a][:b][:c][:d][:e] end - x.report 'Hash#[] ||' do + x.report "Hash#[] ||" do ((((h[:a] || {})[:b] || {})[:c] || {})[:d] || {})[:e] end - x.report 'Hash#[] &&' do + x.report "Hash#[] &&" do h[:a] && h[:a][:b] && h[:a][:b][:c] && h[:a][:b][:c][:d] && h[:a][:b][:c][:d][:e] end - x.report 'Hash#fetch' do + x.report "Hash#fetch" do h.fetch(:a).fetch(:b).fetch(:c).fetch(:d).fetch(:e) end - x.report 'Hash#fetch fallback' do + x.report "Hash#fetch fallback" do h.fetch(:a, {}).fetch(:b, {}).fetch(:c, {}).fetch(:d, {}).fetch(:e, nil) end