From a24912cb1d34912a16aa27d952beff825e558f1f Mon Sep 17 00:00:00 2001 From: Michael Lovitt Date: Thu, 18 May 2017 15:38:30 -0500 Subject: Performance optimization for AttributeSet#deep_dup Skip the call to #dup, since it does a shallow copy of attributes, which is wasted effort, since #deep_dup then replaces that shallow copy with a #deep_dup of the given attributes. This change addresses slowness in ActiveRecord initialization introduced starting in Rails 5.0. --- activerecord/lib/active_record/attribute_set.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/attribute_set.rb b/activerecord/lib/active_record/attribute_set.rb index 66b278219a..abe8e14f26 100644 --- a/activerecord/lib/active_record/attribute_set.rb +++ b/activerecord/lib/active_record/attribute_set.rb @@ -64,9 +64,7 @@ module ActiveRecord end def deep_dup - dup.tap do |copy| - copy.instance_variable_set(:@attributes, attributes.deep_dup) - end + self.class.new(attributes.deep_dup) end def initialize_dup(_) -- cgit v1.2.3 From bfc62febac905412cdbcb7698d5a3b3ea5167af3 Mon Sep 17 00:00:00 2001 From: Michael Lovitt Date: Thu, 18 May 2017 15:43:49 -0500 Subject: Performance optimization for ActiveRecord#subclass_from_attributes This change addresses slowness in ActiveRecord initialization introduced starting in Rails 5.0. --- activerecord/lib/active_record/inheritance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb index fbdaeaae51..236a65eba7 100644 --- a/activerecord/lib/active_record/inheritance.rb +++ b/activerecord/lib/active_record/inheritance.rb @@ -217,7 +217,7 @@ module ActiveRecord def subclass_from_attributes(attrs) attrs = attrs.to_h if attrs.respond_to?(:permitted?) if attrs.is_a?(Hash) - subclass_name = attrs.with_indifferent_access[inheritance_column] + subclass_name = attrs[inheritance_column] || attrs[inheritance_column.to_sym] if subclass_name.present? find_sti_class(subclass_name) -- cgit v1.2.3 From 63dd12b7b83541d8a469a8e6aed1607d77f0d994 Mon Sep 17 00:00:00 2001 From: Michael Lovitt Date: Thu, 18 May 2017 15:52:45 -0500 Subject: Performance optimization for ActiveRecord#column_defaults Memoize the #column_defaults class property, as ActiveRecord does for other properties in this module. This change addresses slowness in ActiveRecord initialization introduced starting in Rails 5.0. This method's performance has not changed with Rails 5, but it is now called much more frequently than before: every time an STI model is instantiated. --- activerecord/lib/active_record/model_schema.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb index 54216caaaf..aa9087fae3 100644 --- a/activerecord/lib/active_record/model_schema.rb +++ b/activerecord/lib/active_record/model_schema.rb @@ -377,7 +377,7 @@ module ActiveRecord # default values when instantiating the Active Record object for this table. def column_defaults load_schema - _default_attributes.to_hash + @column_defaults ||= _default_attributes.to_hash end def _default_attributes # :nodoc: @@ -466,6 +466,7 @@ module ActiveRecord @attribute_types = nil @content_columns = nil @default_attributes = nil + @column_defaults = nil @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column @attributes_builder = nil @columns = nil -- cgit v1.2.3 From fb6ccce80663dad034d86c472024076a8348a12f Mon Sep 17 00:00:00 2001 From: Michael Lovitt Date: Thu, 25 May 2017 17:14:33 -0500 Subject: Make #deep_dup use #allocate instead of #new This change preserves the speedup made in a24912cb1d3 (by avoiding the wasted shallow dup of @attributes) while ensuring that the performance of #deep_dup won't be tied to the performance of #initialize --- activerecord/lib/active_record/attribute_set.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/attribute_set.rb b/activerecord/lib/active_record/attribute_set.rb index abe8e14f26..01f9d815d5 100644 --- a/activerecord/lib/active_record/attribute_set.rb +++ b/activerecord/lib/active_record/attribute_set.rb @@ -64,7 +64,9 @@ module ActiveRecord end def deep_dup - self.class.new(attributes.deep_dup) + self.class.allocate.tap do |copy| + copy.instance_variable_set(:@attributes, attributes.deep_dup) + end end def initialize_dup(_) -- cgit v1.2.3