Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hash#merge({}) vs Hash#dup#merge!({}) vs {}#merge!(Hash) #42

Closed
wants to merge 2 commits into from

Conversation

@bejmuller
Copy link
Contributor

commented Jul 7, 2015

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:

$ ruby -v code/hash/merge-vs-dup-merge-bang-vs-merge-bang.rb 
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
Calculating -------------------------------------
      Hash#merge({})   603.000  i/100ms
 Hash#dup#merge!({})   650.000  i/100ms
     {}#merge!(Hash)     1.763k i/100ms
-------------------------------------------------
      Hash#merge({})      6.593k (± 7.6%) i/s -     33.165k
 Hash#dup#merge!({})      6.591k (± 5.2%) i/s -     33.150k
     {}#merge!(Hash)     17.654k (± 3.0%) i/s -     89.913k

Comparison:
     {}#merge!(Hash):    17654.0 i/s
      Hash#merge({}):     6592.7 i/s - 2.68x slower
 Hash#dup#merge!({}):     6591.2 i/s - 2.68x slower

@bejmuller bejmuller changed the title Hash#merge({})` vs `Hash#dup#merge!({})` vs `{}#merge!(Hash) Hash#merge({}) vs Hash#dup#merge!({}) vs {}#merge!(Hash) Jul 7, 2015

@JuanitoFatas

This comment has been minimized.

Copy link
Owner

commented Aug 11, 2015

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!

@bejmuller

This comment has been minimized.

Copy link
Contributor Author

commented Aug 11, 2015

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...

@JuanitoFatas JuanitoFatas reopened this Aug 11, 2015

@JuanitoFatas

This comment has been minimized.

Copy link
Owner

commented Aug 11, 2015

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.

👍

I would have appreciated a comment first, and a possibility to reply before closing it right away...

My apologies.

@bejmuller

This comment has been minimized.

Copy link
Contributor Author

commented Aug 11, 2015

No problem :) The description and the title I gave it are not the best, so that could have caused some confusion.

@JuanitoFatas

This comment has been minimized.

Copy link
Owner

commented Aug 11, 2015

Thank you Elod! I merged your commits in d83756f and made some minor changes 🙇

Thank you for your contribution 👍 🌠 🌠 🌠 🌠 🌠

@krzysiek1507

This comment has been minimized.

Copy link

commented Apr 18, 2019

{}#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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.