1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

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.
This commit is contained in:
Eugene Kenny 2018-04-08 22:56:31 +01:00
parent d729bc7488
commit b9e1c0c4d7
2 changed files with 9 additions and 1 deletions

View file

@ -11,6 +11,10 @@ module ActiveModel
@forced_changes = Set.new @forced_changes = Set.new
end end
def changed_attribute_names
attr_names.select { |attr_name| changed?(attr_name) }
end
def changed_values def changed_values
attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result| attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
if changed?(attr_name) if changed?(attr_name)
@ -76,6 +80,10 @@ module ActiveModel
class NullMutationTracker # :nodoc: class NullMutationTracker # :nodoc:
include Singleton include Singleton
def changed_attribute_names(*)
[]
end
def changed_values(*) def changed_values(*)
{} {}
end end

View file

@ -114,7 +114,7 @@ module ActiveRecord
# Alias for +changed+ # Alias for +changed+
def changed_attribute_names_to_save def changed_attribute_names_to_save
changes_to_save.keys mutations_from_database.changed_attribute_names
end end
# Alias for +changed_attributes+ # Alias for +changed_attributes+