From 975c9c9d4498a4b4a00de713e932abe3299a4007 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 10 Sep 2013 18:07:54 +1000 Subject: Perf: avoid dupes add fallback logic for coders --- activerecord/lib/active_record/attribute_methods/read.rb | 15 ++++++++------- activerecord/lib/active_record/core.rb | 6 ++++-- activerecord/lib/active_record/persistence.rb | 5 +++-- activerecord/test/cases/serialized_attribute_test.rb | 2 +- 4 files changed, 16 insertions(+), 12 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 1cf3aba41c..c152a246b5 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -109,13 +109,14 @@ module ActiveRecord # We use #[] first as a perf optimization for non-nil values. See https://gist.github.com/jonleighton/3552829. name = attr_name.to_s @attributes_cache[name] || @attributes_cache.fetch(name) { - column = @columns_hash.fetch(name) { - return @attributes.fetch(name) { - if name == 'id' && self.class.primary_key != name - read_attribute(self.class.primary_key) - end - } - } + column = @column_types_override[name] if @column_types_override + column ||= @column_types[name] + + return @attributes.fetch(name) { + if name == 'id' && self.class.primary_key != name + read_attribute(self.class.primary_key) + end + } unless column value = @attributes.fetch(name) { return block_given? ? yield(name) : nil diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 2b1e997ef4..b4d6474caa 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -168,7 +168,8 @@ module ActiveRecord defaults.each { |k, v| defaults[k] = v.dup if v.duplicable? } @attributes = self.class.initialize_attributes(defaults) - @columns_hash = self.class.column_types.dup + @column_types_override = nil + @column_types = self.class.column_types init_internals init_changed_attributes @@ -193,7 +194,8 @@ module ActiveRecord # post.title # => 'hello world' def init_with(coder) @attributes = self.class.initialize_attributes(coder['attributes']) - @columns_hash = self.class.column_types.merge(coder['column_types'] || {}) + @column_types_override = coder['column_types'] + @column_types = self.class.column_types init_internals diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 582006ea7d..2f3fc7bd50 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -383,9 +383,10 @@ module ActiveRecord end @attributes.update(fresh_object.instance_variable_get('@attributes')) - @columns_hash = fresh_object.instance_variable_get('@columns_hash') - @attributes_cache = {} + @column_types = self.class.column_types + @column_types_override = fresh_object.instance_variable_get('@columns_types_override') + @attributes_cache = {} self end diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb index b49c27bc78..24c5f330a1 100644 --- a/activerecord/test/cases/serialized_attribute_test.rb +++ b/activerecord/test/cases/serialized_attribute_test.rb @@ -245,7 +245,7 @@ class SerializedAttributeTest < ActiveRecord::TestCase Topic.create(content: myobj) Topic.all.each do |topic| - type = topic.instance_variable_get("@columns_hash")["content"] + type = Topic.column_types["content"] assert !type.instance_variable_get("@column").is_a?(ActiveRecord::AttributeMethods::Serialization::Type) end end -- cgit v1.2.3