Skip to content

Commit

Permalink
Use transform_values to build hash_rows
Browse files Browse the repository at this point in the history
This commit changes hash_rows to build the first row as it did before,
and then to use transform_values to build subsequent rows, using the
first as a template.

In Ruby 2.4+ (first version to include transform_values) this is
marginally faster because the hash will never be realloc'd and the hash
update logic is probably slightly simpler than add.

In Ruby 2.7+ this is a fair bit faster because transform_values is able
to run without hashing the keys and only iterates over the values list.

In the case that we only have one row this is only one extra lvar
set/read and the condition.
  • Loading branch information
jhawthorn committed Oct 31, 2019
1 parent cb740af commit d495eae
Showing 1 changed file with 23 additions and 12 deletions.
35 changes: 23 additions & 12 deletions activerecord/lib/active_record/result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,21 +145,32 @@ def hash_rows
# used as keys in ActiveRecord::Base's @attributes hash
columns = @columns.map(&:-@)
length = columns.length
template = nil

@rows.map { |row|
# In the past we used Hash[columns.zip(row)]
# though elegant, the verbose way is much more efficient
# both time and memory wise cause it avoids a big array allocation
# this method is called a lot and needs to be micro optimised
hash = {}

index = 0
while index < length
hash[columns[index]] = row[index]
index += 1
if template
# We use transform_values to build subsequent rows from the
# hash of the first row. This is faster because we avoid any
# reallocs and in Ruby 2.7+ avoid hashing entirely.
index = -1
template.transform_values do
row[index += 1]
end
else
# In the past we used Hash[columns.zip(row)]
# though elegant, the verbose way is much more efficient
# both time and memory wise cause it avoids a big array allocation
# this method is called a lot and needs to be micro optimised
hash = {}

index = 0
while index < length
hash[columns[index]] = row[index]
index += 1
end

template = hash
end

hash
}
end
end
Expand Down

0 comments on commit d495eae

Please sign in to comment.