Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up homogeneous AR lists / reduce allocations #33223

Merged
merged 4 commits into from Jun 26, 2018

Commits on Jun 25, 2018

  1. Speed up homogeneous AR lists / reduce allocations

    This commit speeds up allocating homogeneous lists of AR objects.  We
    can know if the result set contains an STI column before initializing
    every AR object, so this change pulls the "does this result set contain
    an STI column?" test up, then uses a specialized instantiation function.
    This way we only have to check for an STI column once rather than N
    times.
    
    This change also introduces a new initialization function that is meant
    for use when allocating AR objects that come from the database.  Doing
    this allows us to eliminate one hash allocation per AR instance.
    
    Here is a benchmark:
    
    ```ruby
    require 'active_record'
    require 'benchmark/ips'
    
    ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
    
    ActiveRecord::Migration.verbose = false
    
    ActiveRecord::Schema.define do
      create_table :users, force: true do |t|
        t.string :name
        t.timestamps null: false
      end
    end
    
    class User < ActiveRecord::Base; end
    
    2000.times do
      User.create!(name: "Gorby")
    end
    
    Benchmark.ips do |x|
      x.report("find") do
        User.limit(2000).to_a
      end
    end
    ```
    
    Results:
    
    Before:
    
    ```
    [aaron@TC activerecord (master)]$ be ruby -I lib:~/git/allocation_tracer/lib speed.rb
    Warming up --------------------------------------
                    find     5.000  i/100ms
    Calculating -------------------------------------
                    find     56.192  (± 3.6%) i/s -    285.000  in   5.080940s
    ```
    
    After:
    
    ```
    [aaron@TC activerecord (homogeneous-allocation)]$ be ruby -I lib:~/git/allocation_tracer/lib speed.rb
    Warming up --------------------------------------
                    find     7.000  i/100ms
    Calculating -------------------------------------
                    find     72.204  (± 2.8%) i/s -    364.000  in   5.044592s
    ```
    tenderlove committed Jun 25, 2018
    Copy the full SHA
    7d58fa8 View commit details
    Browse the repository at this point in the history

Commits on Jun 26, 2018

  1. Merge branch 'master' into homogeneous-allocation

    * master:
      Call initialize after allocate
      Remove `ActiveSupport::Concern` from `ActiveRecord::Aggregations`
      Add example for no_touching? in active_record/no_touching for api docs [ci skip]
      Generate a new key for each service test
    tenderlove committed Jun 26, 2018
    Copy the full SHA
    259bf87 View commit details
    Browse the repository at this point in the history
  2. define attribute methods in init_from_db

    Now that `allocate` is removed, we need to define attribute methods in
    all "init" methods.
    tenderlove committed Jun 26, 2018
    Copy the full SHA
    a01de4d View commit details
    Browse the repository at this point in the history
  3. Copy the full SHA
    1cec4e1 View commit details
    Browse the repository at this point in the history