diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-04-22 14:41:00 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-04-22 14:41:00 +0900 |
commit | b6828fc91531ae0cc0a0f216705dd19112596301 (patch) | |
tree | ccff8b37db7f15d86fe128085640827269ba8eea /activerecord/lib/active_record/persistence.rb | |
parent | 02b5b8cb4357fe0eda3a5cc0afcfe3ff9f300806 (diff) | |
download | rails-b6828fc91531ae0cc0a0f216705dd19112596301.tar.gz rails-b6828fc91531ae0cc0a0f216705dd19112596301.tar.bz2 rails-b6828fc91531ae0cc0a0f216705dd19112596301.zip |
PERF: 20% faster pk attribute access
I've realized that `user.id` is 20% slower than `user.name` in the
benchmark (https://github.com/rails/rails/pull/35987#issuecomment-483882480).
The reason that performance difference is that `self.class.primary_key`
method call is a bit slow.
Avoiding that method call will make almost attribute access faster and
`user.id` will be completely the same performance with `user.name`.
Before (02b5b8cb):
```
Warming up --------------------------------------
user.id 140.535k i/100ms
user['id'] 96.549k i/100ms
user.name 158.110k i/100ms
user['name'] 94.507k i/100ms
user.changed? 19.003k i/100ms
user.saved_changes? 25.404k i/100ms
Calculating -------------------------------------
user.id 2.231M (± 0.9%) i/s - 11.243M in 5.040066s
user['id'] 1.310M (± 1.3%) i/s - 6.565M in 5.012607s
user.name 2.683M (± 1.2%) i/s - 13.439M in 5.009392s
user['name'] 1.322M (± 0.9%) i/s - 6.615M in 5.003239s
user.changed? 201.999k (±10.9%) i/s - 1.007M in 5.091195s
user.saved_changes? 258.214k (±17.1%) i/s - 1.245M in 5.007421s
```
After (this change):
```
Warming up --------------------------------------
user.id 158.364k i/100ms
user['id'] 106.412k i/100ms
user.name 158.644k i/100ms
user['name'] 107.518k i/100ms
user.changed? 19.082k i/100ms
user.saved_changes? 24.886k i/100ms
Calculating -------------------------------------
user.id 2.768M (± 1.1%) i/s - 13.936M in 5.034957s
user['id'] 1.507M (± 2.1%) i/s - 7.555M in 5.017211s
user.name 2.727M (± 1.5%) i/s - 13.643M in 5.004766s
user['name'] 1.521M (± 1.3%) i/s - 7.634M in 5.018321s
user.changed? 200.865k (±11.1%) i/s - 992.264k in 5.044868s
user.saved_changes? 269.652k (±10.5%) i/s - 1.344M in 5.077972s
```
Diffstat (limited to 'activerecord/lib/active_record/persistence.rb')
-rw-r--r-- | activerecord/lib/active_record/persistence.rb | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index bd572486c8..1ff7ee4d89 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -353,6 +353,7 @@ module ActiveRecord end def _insert_record(values) # :nodoc: + primary_key = self.primary_key primary_key_value = nil if primary_key && Hash === values @@ -674,7 +675,7 @@ module ActiveRecord affected_rows = self.class._update_record( attributes, - self.class.primary_key => id_in_database + @primary_key => id_in_database ) affected_rows == 1 @@ -874,7 +875,7 @@ module ActiveRecord end def _delete_row - self.class._delete_record(self.class.primary_key => id_in_database) + self.class._delete_record(@primary_key => id_in_database) end def _touch_row(attribute_names, time) @@ -890,7 +891,7 @@ module ActiveRecord def _update_row(attribute_names, attempted_action = "update") self.class._update_record( attributes_with_values(attribute_names), - self.class.primary_key => id_in_database + @primary_key => id_in_database ) end @@ -928,7 +929,7 @@ module ActiveRecord attributes_with_values(attribute_names) ) - self.id ||= new_id if self.class.primary_key + self.id ||= new_id if @primary_key @new_record = false |