From 0f29c216074c5da6644feddb5184c4881c078b0d Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Fri, 14 Nov 2014 11:20:28 -0700 Subject: Reduce the amount of work performed when instantiating AR models We don't know which attributes will or won't be used, and we don't want to create massive bottlenecks at instantiation. Rather than doing *any* iteration over types and values, we can lazily instantiate the object. The lazy attribute hash should not fully implement hash, or subclass hash at any point in the future. It is not meant to be a replacement, but instead implement its own interface which happens to overlap. --- activerecord/lib/active_record/attribute_set.rb | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'activerecord/lib/active_record/attribute_set.rb') diff --git a/activerecord/lib/active_record/attribute_set.rb b/activerecord/lib/active_record/attribute_set.rb index 98ac63c7e1..21c58cbf1d 100644 --- a/activerecord/lib/active_record/attribute_set.rb +++ b/activerecord/lib/active_record/attribute_set.rb @@ -2,8 +2,6 @@ require 'active_record/attribute_set/builder' module ActiveRecord class AttributeSet # :nodoc: - delegate :keys, to: :initialized_attributes - def initialize(attributes) @attributes = attributes end @@ -25,6 +23,10 @@ module ActiveRecord attributes.key?(name) && self[name].initialized? end + def keys + attributes.initialized_keys + end + def fetch_value(name, &block) self[name].value(&block) end @@ -43,7 +45,7 @@ module ActiveRecord end def initialize_dup(_) - @attributes = attributes.transform_values(&:dup) + @attributes = attributes.dup super end @@ -58,12 +60,6 @@ module ActiveRecord end end - def ensure_initialized(key) - unless self[key].initialized? - write_from_database(key, nil) - end - end - protected attr_reader :attributes -- cgit v1.2.3 From 08576b94ad4f19dfc368619d7751e211d23dcad8 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 18 Nov 2014 15:19:15 -0800 Subject: Improve the performance of reading attributes We added a comparison to "id", and call to `self.class.primary_key` a *lot*. We also have performance hits from `&block` all over the place. We skip the check in a new method, in order to avoid breaking the behavior of `read_attribute` --- activerecord/lib/active_record/attribute_set.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/attribute_set.rb') diff --git a/activerecord/lib/active_record/attribute_set.rb b/activerecord/lib/active_record/attribute_set.rb index 21c58cbf1d..6b1d7ea79e 100644 --- a/activerecord/lib/active_record/attribute_set.rb +++ b/activerecord/lib/active_record/attribute_set.rb @@ -27,8 +27,8 @@ module ActiveRecord attributes.initialized_keys end - def fetch_value(name, &block) - self[name].value(&block) + def fetch_value(name) + self[name].value { |n| yield n if block_given? } end def write_from_database(name, value) -- cgit v1.2.3