mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
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
This commit is contained in:
parent
9bf772d936
commit
0675210c95
1 changed files with 18 additions and 9 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue