From d82dafe65c1137a2f84975c202d471054533f7bc Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Thu, 12 Jun 2014 09:00:03 -0600 Subject: Fix performance regression on preloading HABTM associations We'd spend a lot of time calling `hash` and `eql?` on the join model, which has no primary key. Calling `id` with no primary key is a really slow way to get back `nil`, so we can improve the performance there. However, even with the escape clause, we *still* weren't getting high enough performance, as we were checking the primary key too much. `hash` will always return `nil.hash` for records with no id, and `==` will always return `false`. We can optimize those cases in the HABTM join model. --- activerecord/lib/active_record/attribute_methods/primary_key.rb | 1 + activerecord/lib/active_record/core.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb index 931209b07b..cb550b0683 100644 --- a/activerecord/lib/active_record/attribute_methods/primary_key.rb +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -15,6 +15,7 @@ module ActiveRecord # Returns the primary key value. def id + return unless self.class.primary_key sync_with_transaction_state read_attribute(self.class.primary_key) end diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 7edaf256c7..6d1897ab40 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -380,7 +380,7 @@ module ActiveRecord # Delegates to id in order to allow two records of the same type and id to work with something like: # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ] def hash - id.hash + (id || object_id).hash end # Clone and freeze the attributes hash such that associations are still -- cgit v1.2.3