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.

Reply via email to