• G
    Reduce calls to stringify_keys. · 47e06c98
    Guo Xiang Tan 提交于
    Stackprof output truncated.
    ```
    TOTAL    (pct)     SAMPLES    (pct)     FRAME
      23   (4.7%)          12   (2.4%)     Hash#transform_keys
      11   (2.2%)          11   (2.2%)     block in Hash#transform_keys
      30   (6.1%)           7   (1.4%)     Hash#stringify_keys
    ```
    
    Benchmark Script:
    ```
    begin
      require 'bundler/inline'
    rescue LoadError => e
      $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
      raise e
    end
    
    gemfile(true) do
      source 'https://rubygems.org'
      gem 'rails', path: '~/rails' # master against ref "f1f0a3f8"
      gem 'arel', github: 'rails/arel', branch: 'master'
      gem 'rack', github: 'rack/rack', branch: 'master'
      gem 'sass'
      gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
      gem 'sprockets', github: 'rails/sprockets', branch: 'master'
      gem 'pg'
      gem 'benchmark-ips'
    end
    
    require 'active_record'
    require 'benchmark/ips'
    
    ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
    
    ActiveRecord::Migration.verbose = false
    
    ActiveRecord::Schema.define do
      create_table :users, force: true do |t|
        t.string :name, :email
        t.timestamps null: false
      end
    end
    
    class User < ActiveRecord::Base; end
    
    attributes = {
      name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
      email: "foobar@email.com",
    }
    
    1000.times { User.create!(attributes) }
    
    Benchmark.ips(5, 3) do |x|
      x.report('where with hash') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
      x.report('where with string') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
      x.compare!
    end
    
    key =
      if RUBY_VERSION < '2.2'
        :total_allocated_object
      else
        :total_allocated_objects
      end
    
    before = GC.stat[key]
    User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
    after = GC.stat[key]
    puts "Total Allocated Object: #{after - before}"
    ```
    
    Before:
    ```
    Calculating -------------------------------------
         where with hash     2.796k i/100ms
       where with string     4.338k i/100ms
    -------------------------------------------------
         where with hash     29.177k (± 1.5%) i/s -    148.188k
       where with string     47.419k (± 2.8%) i/s -    238.590k
    
    Comparison:
       where with string:    47419.0 i/s
         where with hash:    29176.6 i/s - 1.63x slower
    
    Total Allocated Object: 85
    ```
    
    After:
    ```
    Calculating -------------------------------------
         where with hash     2.895k i/100ms
       where with string     4.416k i/100ms
    -------------------------------------------------
         where with hash     30.758k (± 2.0%) i/s -    156.330k
       where with string     47.708k (± 2.6%) i/s -    238.464k
    
    Comparison:
       where with string:    47707.9 i/s
         where with hash:    30757.7 i/s - 1.55x slower
    
    Total Allocated Object: 84
    ```
    47e06c98
where_clause_factory.rb 904 字节