-
Daniel Pepper authored
Is there a reason we're only taking this short cut for frozen strings and not other immutable objects commonly used as hash keys (eg. symbols and integers)? initial tests suggest a ~30% performance improvement... ``` require 'benchmark' class Object def deep_dup dup end alias deep_dup_all deep_dup end class Hash def deep_dup hash = dup each_pair do |key, value| if key.frozen? && ::String === key hash[key] = value.deep_dup else hash.delete(key) hash[key.deep_dup] = value.deep_dup end end hash end def deep_dup_all hash = dup each_pair do |key, value| if key.frozen? hash[key] = value.deep_dup_all else hash.delete(key) hash[key.deep_dup_all] = value.deep_dup_all end end hash end end data = Hash[('aaa'..'zzz').map {|k| [k.to_sym, k]}] control = Benchmark.realtime do 30.times { data.deep_dup } end experiment = Benchmark.realtime do 30.times { data.deep_dup_all } end puts "%.3f v %.3f => %d%% speed up" % [ control, experiment, (control - experiment) / control * 100 ] ```
Daniel Pepper authoredIs there a reason we're only taking this short cut for frozen strings and not other immutable objects commonly used as hash keys (eg. symbols and integers)? initial tests suggest a ~30% performance improvement... ``` require 'benchmark' class Object def deep_dup dup end alias deep_dup_all deep_dup end class Hash def deep_dup hash = dup each_pair do |key, value| if key.frozen? && ::String === key hash[key] = value.deep_dup else hash.delete(key) hash[key.deep_dup] = value.deep_dup end end hash end def deep_dup_all hash = dup each_pair do |key, value| if key.frozen? hash[key] = value.deep_dup_all else hash.delete(key) hash[key.deep_dup_all] = value.deep_dup_all end end hash end end data = Hash[('aaa'..'zzz').map {|k| [k.to_sym, k]}] control = Benchmark.realtime do 30.times { data.deep_dup } end experiment = Benchmark.realtime do 30.times { data.deep_dup_all } end puts "%.3f v %.3f => %d%% speed up" % [ control, experiment, (control - experiment) / control * 100 ] ```
Loading