aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/reflection.rb
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2015-09-08 01:04:22 -0300
committerRafael Mendonça França <rafaelmfranca@gmail.com>2015-09-08 01:04:22 -0300
commit0675210c959153ae826f3ceccb6b4fbcb2783daa (patch)
tree3fc59aae78cadaec5a161f4ee992d74cb069d3dd /activerecord/lib/active_record/reflection.rb
parent9bf772d936c3236267eb8f7a09dde21226125234 (diff)
downloadrails-0675210c959153ae826f3ceccb6b4fbcb2783daa.tar.gz
rails-0675210c959153ae826f3ceccb6b4fbcb2783daa.tar.bz2
rails-0675210c959153ae826f3ceccb6b4fbcb2783daa.zip
Memoized reflections accessor
Its value never change since associations are defined at class load time so there is no need to build the hash everytime the method is called. Before this change: Calculating ------------------------------------- reflections 804.000 i/100ms ------------------------------------------------- reflections 8.213k (±26.2%) i/s - 36.180k After this change: Calculating ------------------------------------- reflections 24.548k i/100ms ------------------------------------------------- reflections 1.591M (±25.7%) i/s - 7.364M Benchmark script: require 'bundler/setup' require 'active_record' require 'benchmark/ips' ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') ActiveRecord::Migration.verbose = false ActiveRecord::Schema.define do 100.times do |i| create_table "users#{i}", force: true end create_table :cars, force: true do |t| 100.times do |i| t.references "users#{i}" end end end class Car < ActiveRecord::Base 100.times do |i| belongs_to "users#{i}".to_sym end end Benchmark.ips do |x| x.report('reflections') { Car.reflections } end
Diffstat (limited to 'activerecord/lib/active_record/reflection.rb')
-rw-r--r--activerecord/lib/active_record/reflection.rb27
1 files changed, 18 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 5360db6a19..e7f56d09e3 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -32,6 +32,7 @@ module ActiveRecord
end
def self.add_reflection(ar, name, reflection)
+ ar.clear_reflections_cache
ar._reflections = ar._reflections.merge(name.to_s => reflection)
end
@@ -67,18 +68,22 @@ module ActiveRecord
#
# @api public
def reflections
- ref = {}
- _reflections.each do |name, reflection|
- parent_reflection = reflection.parent_reflection
+ @__reflections ||= begin
+ ref = {}
- if parent_reflection
- parent_name = parent_reflection.name
- ref[parent_name.to_s] = parent_reflection
- else
- ref[name] = reflection
+ _reflections.each do |name, reflection|
+ parent_reflection = reflection.parent_reflection
+
+ if parent_reflection
+ parent_name = parent_reflection.name
+ ref[parent_name.to_s] = parent_reflection
+ else
+ ref[name] = reflection
+ end
end
+
+ ref
end
- ref
end
# Returns an array of AssociationReflection objects for all the
@@ -118,6 +123,10 @@ module ActiveRecord
def reflect_on_all_autosave_associations
reflections.values.select { |reflection| reflection.options[:autosave] }
end
+
+ def clear_reflections_cache #:nodoc:
+ @__reflection = nil
+ end
end
# Holds all the methods that are shared between MacroReflection, AssociationReflection