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

Avoid redundant attribute_alias? before attribute_alias

If we want to get alias resolved attribute finally, we can use
`attribute_alias` directly.

For that purpose, avoiding redundant `attribute_alias?` makes alias
attribute access 40% faster.

https://gist.github.com/kamipo/e427f080a27b46f50bc508fae3612a0e

Before (2c0729d8):

```
Warming up --------------------------------------
          user['id']   102.668k i/100ms
      user['new_id']    80.660k i/100ms
        user['name']    99.368k i/100ms
    user['new_name']    81.626k i/100ms
Calculating -------------------------------------
          user['id']      1.431M (± 4.0%) i/s -      7.187M in   5.031985s
      user['new_id']      1.042M (± 4.2%) i/s -      5.243M in   5.039858s
        user['name']      1.406M (± 5.6%) i/s -      7.055M in   5.036743s
    user['new_name']      1.074M (± 3.6%) i/s -      5.387M in   5.024152s
```

After (this change):

```
Warming up --------------------------------------
          user['id']   109.775k i/100ms
      user['new_id']   103.303k i/100ms
        user['name']   105.988k i/100ms
    user['new_name']    99.618k i/100ms
Calculating -------------------------------------
          user['id']      1.520M (± 6.7%) i/s -      7.574M in   5.011496s
      user['new_id']      1.485M (± 6.2%) i/s -      7.438M in   5.036252s
        user['name']      1.538M (± 5.4%) i/s -      7.737M in   5.049765s
    user['new_name']      1.516M (± 4.6%) i/s -      7.571M in   5.007293s
```
This commit is contained in:
Ryuta Kamizono 2019-04-22 18:12:14 +09:00
parent b7c7f9bb80
commit 5575bd7b22
9 changed files with 24 additions and 31 deletions

View file

@ -116,22 +116,17 @@ module ActiveModel
private private
def write_attribute(attr_name, value) def write_attribute(attr_name, value)
name = if self.class.attribute_alias?(attr_name) name = attr_name.to_s
self.class.attribute_alias(attr_name).to_s name = self.class.attribute_aliases[name] || name
else
attr_name.to_s
end
@attributes.write_from_user(name, value) @attributes.write_from_user(name, value)
value value
end end
def attribute(attr_name) def attribute(attr_name)
name = if self.class.attribute_alias?(attr_name) name = attr_name.to_s
self.class.attribute_alias(attr_name).to_s name = self.class.attribute_aliases[name] || name
else
attr_name.to_s
end
@attributes.fetch_value(name) @attributes.fetch_value(name)
end end

View file

@ -167,12 +167,8 @@ module ActiveRecord
end end
def write_attribute_without_type_cast(attr_name, value) def write_attribute_without_type_cast(attr_name, value)
name = attr_name.to_s result = super
if self.class.attribute_alias?(name) clear_attribute_change(attr_name)
name = self.class.attribute_alias(name)
end
result = super(name, value)
clear_attribute_change(name)
result result
end end

View file

@ -27,9 +27,7 @@ module ActiveRecord
# to a date object, like Date.new(2004, 12, 12)). # to a date object, like Date.new(2004, 12, 12)).
def read_attribute(attr_name, &block) def read_attribute(attr_name, &block)
name = attr_name.to_s name = attr_name.to_s
if self.class.attribute_alias?(name) name = self.class.attribute_aliases[name] || name
name = self.class.attribute_alias(name)
end
name = @primary_key if name == "id" && @primary_key name = @primary_key if name == "id" && @primary_key
_read_attribute(name, &block) _read_attribute(name, &block)

View file

@ -31,9 +31,7 @@ module ActiveRecord
# turned into +nil+. # turned into +nil+.
def write_attribute(attr_name, value) def write_attribute(attr_name, value)
name = attr_name.to_s name = attr_name.to_s
if self.class.attribute_alias?(name) name = self.class.attribute_aliases[name] || name
name = self.class.attribute_alias(name)
end
name = @primary_key if name == "id" && @primary_key name = @primary_key if name == "id" && @primary_key
_write_attribute(name, value) _write_attribute(name, value)

View file

@ -268,7 +268,8 @@ module ActiveRecord
end end
def arel_attribute(name, table = arel_table) # :nodoc: def arel_attribute(name, table = arel_table) # :nodoc:
name = attribute_alias(name) if attribute_alias?(name) name = name.to_s
name = attribute_aliases[name] || name
table[name] table[name]
end end

View file

@ -664,8 +664,13 @@ module ActiveRecord
raise ActiveRecordError, "cannot update a new record" if new_record? raise ActiveRecordError, "cannot update a new record" if new_record?
raise ActiveRecordError, "cannot update a destroyed record" if destroyed? raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
attributes = attributes.transform_keys do |key|
name = key.to_s
self.class.attribute_aliases[name] || name
end
attributes.each_key do |key| attributes.each_key do |key|
verify_readonly_attribute(key.to_s) verify_readonly_attribute(key)
end end
id_in_database = self.id_in_database id_in_database = self.id_in_database
@ -853,7 +858,7 @@ module ActiveRecord
attribute_names = timestamp_attributes_for_update_in_model attribute_names = timestamp_attributes_for_update_in_model
attribute_names |= names.map!(&:to_s).map! { |name| attribute_names |= names.map!(&:to_s).map! { |name|
self.class.attribute_alias?(name) ? self.class.attribute_alias(name) : name self.class.attribute_aliases[name] || name
} }
unless attribute_names.empty? unless attribute_names.empty?

View file

@ -1178,7 +1178,7 @@ module ActiveRecord
end end
def arel_column(field) def arel_column(field)
field = klass.attribute_alias(field) if klass.attribute_alias?(field) field = klass.attribute_aliases[field] || field
from = from_clause.name || from_clause.value from = from_clause.name || from_clause.value
if klass.columns_hash.key?(field) && (!from || table_name_matches?(from)) if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))

View file

@ -12,9 +12,9 @@ module ActiveRecord
def resolve_column_aliases(hash) def resolve_column_aliases(hash)
new_hash = hash.dup new_hash = hash.dup
hash.each do |key, _| hash.each_key do |key|
if (key.is_a?(Symbol)) && klass.attribute_alias?(key) if key.is_a?(Symbol) && new_key = klass.attribute_aliases[key.to_s]
new_hash[klass.attribute_alias(key)] = new_hash.delete(key) new_hash[new_key] = new_hash.delete(key)
end end
end end
new_hash new_hash

View file

@ -323,8 +323,8 @@ class FakeKlass
"posts" "posts"
end end
def attribute_alias?(name) def attribute_aliases
false {}
end end
def sanitize_sql(sql) def sanitize_sql(sql)