diff options
author | Lachlan Sylvester <lachlan.sylvester@publicisfrontfoot.com.au> | 2018-06-19 11:11:46 +1000 |
---|---|---|
committer | Lachlan Sylvester <lachlan.sylvester@publicisfrontfoot.com.au> | 2018-06-19 11:11:46 +1000 |
commit | 13f0d6ebd38ad08f7550db784d64c5c6ab7f56f9 (patch) | |
tree | 73c9e62507f6ed4eb627dee35d1083a299bf3f1f /activerecord | |
parent | 433a3122697e41bb46c4f072d2d8223233af5dd4 (diff) | |
download | rails-13f0d6ebd38ad08f7550db784d64c5c6ab7f56f9.tar.gz rails-13f0d6ebd38ad08f7550db784d64c5c6ab7f56f9.tar.bz2 rails-13f0d6ebd38ad08f7550db784d64c5c6ab7f56f9.zip |
Avoid creating temporary arrays in ActiveRecord::Result#cast_values in order to speed up pluck
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/result.rb | 19 | ||||
-rw-r--r-- | activerecord/test/cases/calculations_test.rb | 12 |
2 files changed, 26 insertions, 5 deletions
diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb index 11626c8e31..ffef229be2 100644 --- a/activerecord/lib/active_record/result.rb +++ b/activerecord/lib/active_record/result.rb @@ -97,12 +97,21 @@ module ActiveRecord end def cast_values(type_overrides = {}) # :nodoc: - types = columns.map { |name| column_type(name, type_overrides) } - result = rows.map do |values| - types.zip(values).map { |type, value| type.deserialize(value) } - end + if columns.one? + # Separated to avoid allocating an array per row + + type = column_type(columns.first, type_overrides) - columns.one? ? result.map!(&:first) : result + rows.map do |(value)| + type.deserialize(value) + end + else + types = columns.map { |name| column_type(name, type_overrides) } + + rows.map do |values| + Array.new(values.size) { |i| types[i].deserialize(values[i]) } + end + end end def initialize_copy(other) diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 6ceac59eec..5c9ed42173 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -642,6 +642,18 @@ class CalculationsTest < ActiveRecord::TestCase assert_equal [ topic.written_on ], relation.pluck(:written_on) end + def test_pluck_with_type_cast_does_not_corrupt_the_query_cache + topic = topics(:first) + relation = Topic.where(id: topic.id) + assert_queries 1 do + Topic.cache do + kind = relation.select(:written_on).load.first.read_attribute_before_type_cast(:written_on).class + relation.pluck(:written_on) + assert_kind_of kind, relation.select(:written_on).load.first.read_attribute_before_type_cast(:written_on) + end + end + end + def test_pluck_and_distinct assert_equal [50, 53, 55, 60], Account.order(:credit_limit).distinct.pluck(:credit_limit) end |