Key the attributes hash with symbols
This is a performance/GC optimisation. In theory, this could be optimised by the implementation (last time I checked, this would have no effect on JRuby). But in practise, this make attribute access faster.
This commit is contained in:
parent
e96558f813
commit
86c3dfbd47
|
@ -45,7 +45,7 @@ module ActiveRecord
|
||||||
def define_method_attribute(attr_name)
|
def define_method_attribute(attr_name)
|
||||||
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
||||||
def __temp__
|
def __temp__
|
||||||
read_attribute('#{attr_name}') { |n| missing_attribute(n, caller) }
|
read_attribute(:'#{attr_name}') { |n| missing_attribute(n, caller) }
|
||||||
end
|
end
|
||||||
alias_method '#{attr_name}', :__temp__
|
alias_method '#{attr_name}', :__temp__
|
||||||
undef_method :__temp__
|
undef_method :__temp__
|
||||||
|
@ -68,11 +68,16 @@ module ActiveRecord
|
||||||
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
||||||
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
|
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
|
||||||
def read_attribute(attr_name)
|
def read_attribute(attr_name)
|
||||||
|
return unless attr_name
|
||||||
|
name_sym = attr_name.to_sym
|
||||||
|
|
||||||
# If it's cached, just return it
|
# If it's cached, just return it
|
||||||
@attributes_cache.fetch(attr_name.to_s) { |name|
|
@attributes_cache.fetch(name_sym) {
|
||||||
|
name = attr_name.to_s
|
||||||
|
|
||||||
column = @columns_hash.fetch(name) {
|
column = @columns_hash.fetch(name) {
|
||||||
return @attributes.fetch(name) {
|
return @attributes.fetch(name) {
|
||||||
if name == 'id' && self.class.primary_key != name
|
if name_sym == :id && self.class.primary_key != name
|
||||||
read_attribute(self.class.primary_key)
|
read_attribute(self.class.primary_key)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
@ -83,7 +88,7 @@ module ActiveRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.class.cache_attribute?(name)
|
if self.class.cache_attribute?(name)
|
||||||
@attributes_cache[name] = column.type_cast(value)
|
@attributes_cache[name_sym] = column.type_cast(value)
|
||||||
else
|
else
|
||||||
column.type_cast value
|
column.type_cast value
|
||||||
end
|
end
|
||||||
|
|
|
@ -65,7 +65,7 @@ module ActiveRecord
|
||||||
if (rounded_value != rounded_time) || (!rounded_value && original_time)
|
if (rounded_value != rounded_time) || (!rounded_value && original_time)
|
||||||
write_attribute("#{attr_name}", original_time)
|
write_attribute("#{attr_name}", original_time)
|
||||||
#{attr_name}_will_change!
|
#{attr_name}_will_change!
|
||||||
@attributes_cache["#{attr_name}"] = zoned_time
|
@attributes_cache[:"#{attr_name}"] = zoned_time
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOV
|
EOV
|
||||||
|
|
|
@ -25,13 +25,13 @@ module ActiveRecord
|
||||||
def write_attribute(attr_name, value)
|
def write_attribute(attr_name, value)
|
||||||
attr_name = attr_name.to_s
|
attr_name = attr_name.to_s
|
||||||
attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
|
attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
|
||||||
@attributes_cache.delete(attr_name)
|
@attributes_cache.delete(attr_name.to_sym)
|
||||||
column = column_for_attribute(attr_name)
|
column = column_for_attribute(attr_name)
|
||||||
|
|
||||||
# If we're dealing with a binary column, write the data to the cache
|
# If we're dealing with a binary column, write the data to the cache
|
||||||
# so we don't attempt to typecast multiple times.
|
# so we don't attempt to typecast multiple times.
|
||||||
if column && column.binary?
|
if column && column.binary?
|
||||||
@attributes_cache[attr_name] = value
|
@attributes_cache[attr_name.to_sym] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
if column || @attributes.has_key?(attr_name)
|
if column || @attributes.has_key?(attr_name)
|
||||||
|
|
|
@ -542,10 +542,10 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
||||||
val = t.send attr_name unless attr_name == "type"
|
val = t.send attr_name unless attr_name == "type"
|
||||||
if attribute_gets_cached
|
if attribute_gets_cached
|
||||||
assert cached_columns.include?(attr_name)
|
assert cached_columns.include?(attr_name)
|
||||||
assert_equal val, cache[attr_name]
|
assert_equal val, cache[attr_name.to_sym]
|
||||||
else
|
else
|
||||||
assert uncached_columns.include?(attr_name)
|
assert uncached_columns.include?(attr_name)
|
||||||
assert !cache.include?(attr_name)
|
assert !cache.include?(attr_name.to_sym)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue