From 136fc65c9b8b66e1fb56f3a17f0d1fddff9b4bd0 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Thu, 24 Sep 2015 14:03:27 -0600 Subject: Improve the performance of `save` and friends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The biggest source of the performance regression in these methods occurred because dirty tracking required eagerly materializing and type casting the assigned values. In the previous commits, I've changed dirty tracking to perform the comparisons lazily. However, all of this is moot when calling `save`, since `changes_applied` will be called, which just ends up eagerly materializing everything, anyway. With the new mutation tracker, it's easy to just compare the previous two hashes in the same lazy fashion. We will not have aliasing issues with this setup, which is proven by the fact that we're able to detect nested mutation. Before: User.create! 2.007k (± 7.1%) i/s - 10.098k After: User.create! 2.557k (± 3.5%) i/s - 12.789k Fixes #19859 --- activemodel/lib/active_model/dirty.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activemodel/lib') diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index 0169c20e0b..0ab8df42f5 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -203,7 +203,7 @@ module ActiveModel # Returns +true+ if attr_name were changed before the model was saved, # +false+ otherwise. def previous_changes_include?(attr_name) - @previously_changed.include?(attr_name) + previous_changes.include?(attr_name) end # Removes current changes and makes them accessible through +previous_changes+. @@ -225,7 +225,7 @@ module ActiveModel # Handles *_previous_change for +method_missing+. def attribute_previous_change(attr) - @previously_changed[attr] if attribute_previously_changed?(attr) + previous_changes[attr] if attribute_previously_changed?(attr) end # Handles *_will_change! for +method_missing+. -- cgit v1.2.3