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

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
Copy link
Contributor

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
Copy link
Contributor Author

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
Copy link
Contributor

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
Copy link
Contributor Author

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

@JuanitoFatas
Copy link
Contributor

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

Thank you for your contribution 👍 🌠 🌠 🌠 🌠 🌠

@krzysiek1507
Copy link

{}#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
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants