diff options
author | Eugene Kenny <elkenny@gmail.com> | 2018-04-08 22:56:31 +0100 |
---|---|---|
committer | Eugene Kenny <elkenny@gmail.com> | 2018-04-08 22:56:31 +0100 |
commit | b9e1c0c4d7c67a65c2ea63e7f0925f4d0da306aa (patch) | |
tree | ee77eb11f5cc7ff60a1096801dc89b06b456c770 | |
parent | d729bc748811339c7e536f4ca98e91801e14c6f4 (diff) | |
download | rails-b9e1c0c4d7c67a65c2ea63e7f0925f4d0da306aa.tar.gz rails-b9e1c0c4d7c67a65c2ea63e7f0925f4d0da306aa.tar.bz2 rails-b9e1c0c4d7c67a65c2ea63e7f0925f4d0da306aa.zip |
Avoid generating full changes hash on every save
`changed_attribute_names_to_save` is called in `keys_for_partial_write`,
which is called on every save when partial writes are enabled.
We can avoid generating the full changes hash by asking the mutation
tracker for just the names of the changed attributes. At minimum this
saves one array allocation per attribute, but will also avoid calling
`Attribute#original_value` which is expensive for serialized attributes.
-rw-r--r-- | activemodel/lib/active_model/attribute_mutation_tracker.rb | 8 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/dirty.rb | 2 |
2 files changed, 9 insertions, 1 deletions
diff --git a/activemodel/lib/active_model/attribute_mutation_tracker.rb b/activemodel/lib/active_model/attribute_mutation_tracker.rb index 493be5bb88..82d90664c0 100644 --- a/activemodel/lib/active_model/attribute_mutation_tracker.rb +++ b/activemodel/lib/active_model/attribute_mutation_tracker.rb @@ -11,6 +11,10 @@ module ActiveModel @forced_changes = Set.new end + def changed_attribute_names + attr_names.select { |attr_name| changed?(attr_name) } + end + def changed_values attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result| if changed?(attr_name) @@ -76,6 +80,10 @@ module ActiveModel class NullMutationTracker # :nodoc: include Singleton + def changed_attribute_names(*) + [] + end + def changed_values(*) {} end diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index 3de6fe566d..7224f970e0 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -114,7 +114,7 @@ module ActiveRecord # Alias for +changed+ def changed_attribute_names_to_save - changes_to_save.keys + mutations_from_database.changed_attribute_names end # Alias for +changed_attributes+ |