aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuo Xiang Tan <tgx_world@hotmail.com>2015-07-15 22:00:36 +0800
committerGuo Xiang Tan <tgx_world@hotmail.com>2015-07-16 01:02:15 +0800
commitbeb07fbfae845d20323a9863c7216c6b63aff9c7 (patch)
treeca37bca185b119ec2137632a38dd91aea107f249
parent794252d70990162d14da17ee854ad353e74297ee (diff)
downloadrails-beb07fbfae845d20323a9863c7216c6b63aff9c7.tar.gz
rails-beb07fbfae845d20323a9863c7216c6b63aff9c7.tar.bz2
rails-beb07fbfae845d20323a9863c7216c6b63aff9c7.zip
Revert "Revert "Reduce allocations when running AR callbacks.""
This reverts commit bdc1d329d4eea823d07cf010064bd19c07099ff3. Before: Calculating ------------------------------------- 22.000 i/100ms ------------------------------------------------- 229.700 (± 0.4%) i/s - 1.166k Total Allocated Object: 9939 After: Calculating ------------------------------------- 24.000 i/100ms ------------------------------------------------- 246.443 (± 0.8%) i/s - 1.248k Total Allocated Object: 7939 ``` 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', ref: 'bdc1d329d4eea823d07cf010064bd19c07099ff3' gem 'rails', github: 'rails/rails', ref: 'd2876141d08341ec67cf6a11a073d1acfb920de7' gem 'arel', github: 'rails/arel' gem 'sqlite3' gem 'benchmark-ips' end require 'active_record' require 'benchmark/ips' ActiveRecord::Base.establish_connection('sqlite3::memory:') ActiveRecord::Migration.verbose = false ActiveRecord::Schema.define do create_table :users, force: true do |t| t.string :name, :email t.boolean :admin t.timestamps null: false end end class User < ActiveRecord::Base default_scope { where(admin: true) } end admin = true 1000.times do attributes = { name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", email: "foobar@email.com", admin: admin } User.create!(attributes) admin = !admin end GC.disable Benchmark.ips(5, 3) do |x| x.report { User.all.to_a } end key = if RUBY_VERSION < '2.2' :total_allocated_object else :total_allocated_objects end before = GC.stat[key] User.all.to_a after = GC.stat[key] puts "Total Allocated Object: #{after - before}" ```
-rw-r--r--activemodel/lib/active_model/validations.rb2
-rw-r--r--activemodel/lib/active_model/validations/callbacks.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb2
-rw-r--r--activerecord/lib/active_record/callbacks.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb4
-rw-r--r--activerecord/lib/active_record/core.rb8
-rw-r--r--activerecord/lib/active_record/transactions.rb12
-rw-r--r--activesupport/lib/active_support/callbacks.rb14
8 files changed, 32 insertions, 23 deletions
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index 72094a26c0..5f1dde4aa3 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -404,7 +404,7 @@ module ActiveModel
protected
def run_validations! #:nodoc:
- run_callbacks :validate
+ _run_validate_callbacks
errors.empty?
end
diff --git a/activemodel/lib/active_model/validations/callbacks.rb b/activemodel/lib/active_model/validations/callbacks.rb
index b4301c23e4..4b58ef66e3 100644
--- a/activemodel/lib/active_model/validations/callbacks.rb
+++ b/activemodel/lib/active_model/validations/callbacks.rb
@@ -109,7 +109,7 @@ module ActiveModel
# Overwrite run validations to include callbacks.
def run_validations! #:nodoc:
- run_callbacks(:validation) { super }
+ _run_validation_callbacks { super }
end
end
end
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index cd79266952..1aa6a2ca74 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -133,7 +133,7 @@ module ActiveRecord
if scope.klass.primary_key
count = scope.destroy_all.length
else
- scope.each { |record| record.run_callbacks :destroy }
+ scope.each(&:_run_destroy_callbacks)
arel = scope.arel
diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb
index 3027ce928e..19f0dca5a6 100644
--- a/activerecord/lib/active_record/callbacks.rb
+++ b/activerecord/lib/active_record/callbacks.rb
@@ -289,24 +289,25 @@ module ActiveRecord
end
def destroy #:nodoc:
- run_callbacks(:destroy) { super }
+ _run_destroy_callbacks { super }
end
def touch(*) #:nodoc:
- run_callbacks(:touch) { super }
+ _run_touch_callbacks { super }
end
private
+
def create_or_update(*) #:nodoc:
- run_callbacks(:save) { super }
+ _run_save_callbacks { super }
end
def _create_record #:nodoc:
- run_callbacks(:create) { super }
+ _run_create_callbacks { super }
end
def _update_record(*) #:nodoc:
- run_callbacks(:update) { super }
+ _run_update_callbacks { super }
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 6535121075..282af220fb 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -508,7 +508,7 @@ module ActiveRecord
synchronize do
remove_connection_from_thread_cache conn
- conn.run_callbacks :checkin do
+ conn._run_checkin_callbacks do
conn.expire
end
@@ -764,7 +764,7 @@ module ActiveRecord
end
def checkout_and_verify(c)
- c.run_callbacks :checkout do
+ c._run_checkout_callbacks do
c.verify!
end
c
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 8a014e682e..b82488a59c 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -303,7 +303,7 @@ module ActiveRecord
assign_attributes(attributes) if attributes
yield self if block_given?
- run_callbacks :initialize
+ _run_initialize_callbacks
end
# Initialize an empty model object from +coder+. +coder+ should be
@@ -330,8 +330,8 @@ module ActiveRecord
self.class.define_attribute_methods
- run_callbacks :find
- run_callbacks :initialize
+ _run_find_callbacks
+ _run_initialize_callbacks
self
end
@@ -367,7 +367,7 @@ module ActiveRecord
@attributes = @attributes.dup
@attributes.reset(self.class.primary_key)
- run_callbacks(:initialize)
+ _run_initialize_callbacks
@new_record = true
@destroyed = false
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 6f2def0df1..3131723828 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -319,8 +319,8 @@ module ActiveRecord
end
def before_committed! # :nodoc:
- run_callbacks :before_commit_without_transaction_enrollment
- run_callbacks :before_commit
+ _run_before_commit_without_transaction_enrollment_callbacks
+ _run_before_commit_callbacks
end
# Call the +after_commit+ callbacks.
@@ -329,8 +329,8 @@ module ActiveRecord
# but call it after the commit of a destroyed object.
def committed!(should_run_callbacks: true) #:nodoc:
if should_run_callbacks && destroyed? || persisted?
- run_callbacks :commit_without_transaction_enrollment
- run_callbacks :commit
+ _run_commit_without_transaction_enrollment_callbacks
+ _run_commit_callbacks
end
ensure
force_clear_transaction_record_state
@@ -340,8 +340,8 @@ module ActiveRecord
# state should be rolled back to the beginning or just to the last savepoint.
def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
if should_run_callbacks
- run_callbacks :rollback
- run_callbacks :rollback_without_transaction_enrollment
+ _run_rollback_callbacks
+ _run_rollback_without_transaction_enrollment_callbacks
end
ensure
restore_transaction_record_state(force_restore_state)
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index e8ab3a7db5..f35e1f5098 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -80,8 +80,12 @@ module ActiveSupport
# save
# end
def run_callbacks(kind, &block)
- callbacks = send("_#{kind}_callbacks")
+ send "_run_#{kind}_callbacks", &block
+ end
+
+ private
+ def __run_callbacks__(callbacks, &block)
if callbacks.empty?
yield if block_given?
else
@@ -91,8 +95,6 @@ module ActiveSupport
end
end
- private
-
# A hook invoked every time a before callback is halted.
# This can be overridden in AS::Callback implementors in order
# to provide better debugging/logging.
@@ -806,6 +808,12 @@ module ActiveSupport
names.each do |name|
class_attribute "_#{name}_callbacks"
set_callbacks name, CallbackChain.new(name, options)
+
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def _run_#{name}_callbacks(&block)
+ __run_callbacks__(_#{name}_callbacks, &block)
+ end
+ RUBY
end
end