Please do PR. This is a delicate behavior change, so let's take care that
the hashes are indeed separate objects, defaults are preserved correctly,
etc.

On Tue, Apr 26, 2016 at 2:03 PM Dmitry Gautsel <[email protected]> wrote:

> Hi all.
>
> What do you think about this fix: Hash#dup => Hash[hash]
>
> For example:
>
> 1) Hash#except method:
>
> class Hash
>
>   # current behavior
>   def except(*keys)
>     dup.except!(*keys)
>   end
>
>   # new behavior
>   def except2(*keys)
>     Hash[self].except!(*keys)
>   end
>
>   def except!(*keys)
>     keys.each { |key| delete(key) }
>     self
>   end
> end
>
> hash = { a: 123, b: 23, c: 34 }
>
> Benchmark.ips do |x|
>   x.report('before') { hash.except(:a, :b) }
>   x.report('after') { hash.except2(:a, :b) }
>   x.compare!
> end
>
> Calculating -------------------------------------
>               before    41.756k i/100ms
>                after    62.440k i/100ms
> -------------------------------------------------
>               before    665.171k (± 2.1%) i/s -      3.340M
>                after      1.116M (± 2.4%) i/s -      5.620M
>
> Comparison:
>                after:  1115631.6 i/s
>               before:   665170.7 i/s - 1.68x slower
>
> 2) Hash#deep_merge method (Probably not the best example)
>
> class Hash
>
>   # current behavior
>   def deep_merge(other_hash, &block)
>     dup.deep_merge!(other_hash, &block)
>   end
>
>   # new behavior
>   def deep_merge2(other_hash, &block)
>     Hash[self].deep_merge!(other_hash, &block)
>   end
>
>   def deep_merge!(other_hash, &block)
>     other_hash.each_pair do |current_key, other_value|
>       this_value = self[current_key]
>
>       self[current_key] = if this_value.is_a?(Hash) &&
> other_value.is_a?(Hash)
>         this_value.deep_merge(other_value, &block)
>       else
>         if block_given? && key?(current_key)
>           block.call(current_key, this_value, other_value)
>         else
>           other_value
>         end
>       end
>     end
>
>     self
>   end
> end
>
> h1 = { a: true, b: { c: [1, 2, 3] } }
> h2 = { a: false, b: { x: [3, 4, 5] } }
>
> h1.deep_merge(h2)
>
> Benchmark.ips do |x|
>   x.report('before') { h1.deep_merge(h2) }
>   x.report('after') { h1.deep_merge2(h2) }
>   x.compare!
> end
>
> Calculating -------------------------------------
>               before    22.259k i/100ms
>                after    26.394k i/100ms
> -------------------------------------------------
>               before    297.791k (± 2.4%) i/s -      1.491M
>                after    364.967k (± 1.6%) i/s -      1.848M
>
> Comparison:
>                after:   364967.2 i/s
>               before:   297790.9 i/s - 1.23x slower
>
> If you think it's OK, I will fix it.
>
> Regards, Dmitry.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Ruby on Rails: Core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/rubyonrails-core.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to