Last active
November 23, 2018 16:29
-
-
Save dvandersluis/1fcb26ae809115ef9dfc48fe07b70f18 to your computer and use it in GitHub Desktop.
Rails attribute lookup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark/ips' | |
user = User.last | |
Benchmark.ips do |x| | |
x.report('.attr') { user.name } | |
x.report('[attr]') { user.[]('name') } | |
# What rails calls for user['name'] | |
x.report('read_attr/missing') { user.read_attribute('name') { |n| missing_attribute(n, caller) } } | |
# Drilling down into read_attribute without missing_attribute | |
x.report('read_attribute') { user.read_attribute('name') } | |
x.report('attribute_set[].value') { user.instance_variable_get(:@attributes)['name'].value } | |
# We wouldn't want to do this because type casting is important, but just for curiousity as to how much time | |
# type casting takes | |
x.report('attribute_set[].value_before_type_cast') { user.instance_variable_get(:@attributes)['name'].value_before_type_cast } | |
x.compare! | |
end | |
## Method trace with sources: | |
user[:name] | |
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods.rb#L372-L374 | |
user.read_attribute(:name) { |n| missing_attribute(n, caller) } | |
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/read.rb#L31-L41 | |
user._read_attribute(:name, &block) | |
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/read.rb#L45-L55 | |
user.@attributes.fetch_value('name') { |n| yield n if block_given? } | |
# https://github.com/rails/rails/blob/master/activemodel/lib/active_model/attribute_set.rb#L40-L50 | |
attribute_set['name'] | |
# https://github.com/rails/rails/blob/master/activemodel/lib/active_model/attribute_set.rb#L15-L17 | |
...value | |
# https://github.com/rails/rails/blob/master/activemodel/lib/active_model/attribute.rb#L40-L44 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Warming up -------------------------------------- | |
.attr 148.416k i/100ms | |
[attr] 54.464k i/100ms | |
read_attr/missing 64.984k i/100ms | |
read_attribute 101.857k i/100ms | |
attribute_set[].value | |
171.315k i/100ms | |
attribute_set[].value_before_type_cast | |
181.550k i/100ms | |
Calculating ------------------------------------- | |
.attr 2.802M (± 2.1%) i/s - 14.100M in 5.034267s | |
[attr] 837.030k (± 4.9%) i/s - 4.194M in 5.021677s | |
read_attr/missing 856.952k (± 4.4%) i/s - 4.289M in 5.013995s | |
read_attribute 1.426M (± 2.9%) i/s - 7.130M in 5.002834s | |
attribute_set[].value | |
2.927M (± 3.6%) i/s - 14.733M in 5.040511s | |
attribute_set[].value_before_type_cast | |
3.350M (± 3.5%) i/s - 16.884M in 5.047108s | |
Comparison: | |
attribute_set[].value_before_type_cast: 3349508.8 i/s | |
attribute_set[].value: 2926736.1 i/s - 1.14x slower | |
.attr: 2802032.7 i/s - 1.20x slower | |
read_attribute: 1426429.5 i/s - 2.35x slower | |
read_attr/missing: 856952.2 i/s - 3.91x slower | |
[attr]: 837030.3 i/s - 4.00x slower |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Benchmark.ips do |x| | |
x.report('read_attribute') { user.read_attribute(:name) } | |
x.report('_read_attribute') { user._read_attribute(:name) } | |
x.compare! | |
end | |
# Warming up -------------------------------------- | |
# read_attribute 79.511k i/100ms | |
# _read_attribute 136.627k i/100ms | |
# Calculating ------------------------------------- | |
# read_attribute 1.207M (± 4.4%) i/s - 6.043M in 5.017097s | |
# _read_attribute 2.355M (± 4.8%) i/s - 11.750M in 5.001814s | |
# Comparison: | |
# _read_attribute: 2354831.7 i/s | |
# read_attribute: 1206808.2 i/s - 1.95x slower |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ActiveRecord | |
module AttributeMethods | |
alias_method :old_lookup, :[] | |
def [](attr_name) | |
public_send(attr_name) | |
end | |
end | |
end | |
Benchmark.ips do |x| | |
x.report('old') { tag.old_lookup(:name) } | |
x.report('new') { tag[:name] } | |
x.report('method') { tag.name } | |
x.compare! | |
end | |
# Warming up -------------------------------------- | |
# old 59.763k i/100ms | |
# new 125.890k i/100ms | |
# method 149.602k i/100ms | |
# Calculating ------------------------------------- | |
# old 719.833k (± 4.6%) i/s - 3.646M in 5.075733s | |
# new 2.029M (± 1.9%) i/s - 10.197M in 5.028319s | |
# method 2.341M (± 9.9%) i/s - 11.669M in 5.042085s | |
# Comparison: | |
# method: 2340888.5 i/s | |
# new: 2028720.4 i/s - 1.15x slower | |
# old: 719832.8 i/s - 3.25x slower |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment