aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2015-10-14 18:06:56 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2015-10-14 18:06:56 -0700
commitb6cf69ebcbf7372c61d38aa33baa7d0f4224679b (patch)
treeef904563caae2eb83628c56522aa912059d64763
parent3ad381c3f8598d9920998c8949a96b5f62b280dd (diff)
downloadrails-b6cf69ebcbf7372c61d38aa33baa7d0f4224679b.tar.gz
rails-b6cf69ebcbf7372c61d38aa33baa7d0f4224679b.tar.bz2
rails-b6cf69ebcbf7372c61d38aa33baa7d0f4224679b.zip
freeze the column name to drop string allocations in dirty checks
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
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb2
1 files changed, 1 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index 5e31efec4a..81de7c03fb 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -16,7 +16,7 @@ module ActiveRecord
# +sql_type_metadata+ is various information about the type of the column
# +null+ determines if this column allows +NULL+ values.
def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation = nil)
- @name = name
+ @name = name.freeze
@sql_type_metadata = sql_type_metadata
@null = null
@default = default