Skip to content
  • Daniel Pepper's avatar
    964e7ad1
    deep dup · 964e7ad1
    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 ]
    
    ```
    964e7ad1
    deep dup
    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 ]
    
    ```
Loading