aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/reflection.rb
diff options
context:
space:
mode:
authorGuo Xiang Tan <tgx_world@hotmail.com>2017-09-25 20:29:43 +0800
committerGuo Xiang Tan <tgx_world@hotmail.com>2017-09-25 20:29:43 +0800
commit89711d99b08b5ace8aa5b7394e2ccedb302d118f (patch)
treea5d378d9fe9183842d9f44c4d76b55f1c3a77281 /activerecord/lib/active_record/reflection.rb
parentab08f33f312c20638b9a7c38ee6318727c7f107d (diff)
downloadrails-89711d99b08b5ace8aa5b7394e2ccedb302d118f.tar.gz
rails-89711d99b08b5ace8aa5b7394e2ccedb302d118f.tar.bz2
rails-89711d99b08b5ace8aa5b7394e2ccedb302d118f.zip
PERF: Restore memoization when preloading associations.
Benchmark Script ``` require 'active_record' require 'benchmark/ips' require 'ruby-prof' require 'memory_profiler' require 'byebug' ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) ActiveRecord::Migration.verbose = false ActiveRecord::Schema.define do create_table :users, force: true do |t| t.string :name, :email t.integer :topic_id t.timestamps null: false end create_table :topics, force: true do |t| t.string :title t.timestamps null: false end end attributes = { name: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', email: 'foobar@email.com' } class Topic < ActiveRecord::Base has_many :users end class User < ActiveRecord::Base belongs_to :topic end 100.times do User.create!(attributes) end users = User.first(50) Topic.create!(title: 'This is a topic', users: users) Benchmark.ips do |x| x.config(time: 10, warmup: 5) x.report("preload") do User.includes(:topic).all.to_a end end ``` Before ``` Calculating ------------------------------------- preload 26.000 i/100ms ------------------------------------------------- preload 265.347 (± 3.0%) i/s - 2.652k ``` After ``` Calculating ------------------------------------- preload 39.000 i/100ms ------------------------------------------------- preload 406.053 (± 1.7%) i/s - 4.095k ```
Diffstat (limited to 'activerecord/lib/active_record/reflection.rb')
-rw-r--r--activerecord/lib/active_record/reflection.rb11
1 files changed, 5 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 82ab2415e1..032df925bf 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -425,7 +425,6 @@ module ActiveRecord
def initialize(name, scope, options, active_record)
super
- @automatic_inverse_of = nil
@type = options[:as] && (options[:foreign_type] || "#{options[:as]}_type")
@foreign_type = options[:foreign_type] || "#{name}_type"
@constructable = calculate_constructable(macro, options)
@@ -609,12 +608,14 @@ module ActiveRecord
# If it cannot find a suitable inverse association name, it returns
# +nil+.
def inverse_name
- options.fetch(:inverse_of) do
- @automatic_inverse_of ||= automatic_inverse_of
+ unless defined?(@inverse_name)
+ @inverse_name = options.fetch(:inverse_of) { automatic_inverse_of }
end
+
+ @inverse_name
end
- # returns either false or the inverse association name that it finds.
+ # returns either +nil+ or the inverse association name that it finds.
def automatic_inverse_of
if can_find_inverse_of_automatically?(self)
inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym
@@ -631,8 +632,6 @@ module ActiveRecord
return inverse_name
end
end
-
- false
end
# Checks if the inverse reflection that is returned from the