From c879649a733d982fba9e70f5a280d13636b67c37 Mon Sep 17 00:00:00 2001 From: Eugene Kenny Date: Sun, 18 Jun 2017 15:37:06 +0100 Subject: Improve the performance of writing attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using a similar approach to 08576b94ad4f19dfc368619d7751e211d23dcad8, this change adds a new internal `_write_attribute` method which bypasses the code that checks for attribute aliases and custom primary keys. We can use this method instead of `write_attribute` when we know that we have the name of the actual column to be updated and not an alias. This makes writing an attribute with `attribute=` about 18% faster. Benchmark: ``` 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", github: "rails/rails" gem "arel", github: "rails/arel" gem "sqlite3" gem "benchmark-ips" end require "active_record" ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") ActiveRecord::Schema.define do create_table :posts, force: true do |t| end end class Post < ActiveRecord::Base end post = Post.new(id: 1) Benchmark.ips do |x| x.report("attribute=") { post.id = post.id + 1 } end ``` Before: Warming up -------------------------------------- attribute= 25.889k i/100ms Calculating ------------------------------------- attribute= 290.946k (± 3.1%) i/s - 1.476M in 5.077036s After: Warming up -------------------------------------- attribute= 30.056k i/100ms Calculating ------------------------------------- attribute= 345.088k (± 4.8%) i/s - 1.743M in 5.064264s --- activerecord/lib/active_record/timestamp.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/timestamp.rb') diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index 55f3a194a9..ae50bc6bc1 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -86,7 +86,7 @@ module ActiveRecord all_timestamp_attributes_in_model.each do |column| if !attribute_present?(column) - write_attribute(column, current_time) + _write_attribute(column, current_time) end end end @@ -100,7 +100,7 @@ module ActiveRecord timestamp_attributes_for_update_in_model.each do |column| next if will_save_change_to_attribute?(column) - write_attribute(column, current_time) + _write_attribute(column, current_time) end end super(*args) -- cgit v1.2.3