Closed bejmuller closed 9 years ago
Thanks for the patch! I think dup#merge!
you can just use Hash#merge
. And it is covered by https://github.com/JuanitoFatas/fast-ruby#hashmerge-vs-hashmerge-code. Close this one.
Thanks again!
The reason of opening this PR was to show the difference between {}#merge!(Hash)
vs Hash#merge({})
which is NOT covered anywhere in this repo.
dup.merge!
was just added as a third option (which sometimes is used)
I would have appreciated a comment first, and a possibility to reply before closing it right away...
The reason of opening this PR was to show the difference between {}#merge!(Hash) vs Hash#merge({}) which is NOT covered anywhere in this repo.
:+1:
I would have appreciated a comment first, and a possibility to reply before closing it right away...
My apologies.
No problem :) The description and the title I gave it are not the best, so that could have caused some confusion.
Thank you Elod! I merged your commits in d83756f and made some minor changes :bow:
Thank you for your contribution :+1: :stars: :stars: :stars: :stars: :stars:
{}#merge!(other) do end
is the fastest only when other
has only one key.
Every key more means 10% slow down.
ENUM = (1..100)
ORIGINAL_HASH = { foo: { a: 1, b: { c: 3 } }, bar: {}, baz: "baz", ruby: "ruby", test: "test", yup: "yup", rails: "rails" }
def fast
ENUM.inject([]) do |accumulator, element|
accumulator << ({ bar: element }.merge!(ORIGINAL_HASH) { |_key, left, _right| left })
end
end
def slow
ENUM.inject([]) do |accumulator, element|
accumulator << ORIGINAL_HASH.merge(bar: element)
end
end
def slow_dup
ENUM.inject([]) do |accumulator, element|
accumulator << ORIGINAL_HASH.dup.merge!(bar: element)
end
end
Benchmark.ips do |x|
x.report("{}#merge!(Hash) do end") { fast }
x.report("Hash#merge({})") { slow }
x.report("Hash#dup#merge!({})") { slow_dup }
x.compare!
end
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-darwin18]
Warming up --------------------------------------
{}#merge!(Hash) do end
1.799k i/100ms
Hash#merge({}) 2.956k i/100ms
Hash#dup#merge!({}) 1.217k i/100ms
Calculating -------------------------------------
{}#merge!(Hash) do end
18.216k (± 1.7%) i/s - 91.749k in 5.038319s
Hash#merge({}) 29.844k (± 2.9%) i/s - 150.756k in 5.056616s
Hash#dup#merge!({}) 12.288k (± 2.4%) i/s - 62.067k in 5.054204s
Comparison:
Hash#merge({}): 29844.0 i/s
{}#merge!(Hash) do end: 18215.6 i/s - 1.64x slower
Hash#dup#merge!({}): 12287.7 i/s - 2.43x slower
In some cases we want duplicates of hashes to be created while merging, so I was wondering which one is the fastest way of achieving this: