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