• A
    freeze the column name to drop string allocations in dirty checks · b6cf69eb
    Aaron Patterson 提交于
    Dirty checking keeps a hash where the keys are the column name and the
    value is a dup of the value from the database[1].  This hash is kept for
    every AR object, which means that we dup every column name for every AR
    object that does dirty checking.  Freezing the column name prevents the
    column name from being duped and reduced overall string allocations.
    
    Here is a benchmark to demonstrate:
    
    ```ruby
    require 'active_record'
    
    class Topic < ActiveRecord::Base
    end
    
    20.times do |i|
      Process.waitpid fork {
        ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
    
        ActiveRecord::Base.connection.instance_eval do
          create_table(:topics) do |t|
            t.string   :title, limit: 250
            t.string   :author_name
            t.string   :author_email_address
            t.string   :parent_title
            t.string   :type
            t.string   :group
            i.times do |j|
              t.string :"aaa#{j}"
            end
            t.timestamps null: true
          end
        end
    
        ObjectSpace::AllocationTracer.setup(%i{type})
    
        Topic.create title: "aaron" # heat cache
    
        result = ObjectSpace::AllocationTracer.trace do
          10.times do |i|
            Topic.create title: "aaron #{i}"
          end
        end
    
        puts "#{Topic.columns.length},#{(result.find { |k,v| k.first == :T_STRING }.last.first / 10)}"
      }
    end
    ```
    
    1. https://github.com/rails/rails/blob/3ad381c3f8598d9920998c8949a96b5f62b280dd/activerecord/lib/active_record/attribute_set/builder.rb#L102
    b6cf69eb
column.rb 1.9 KB