mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
drop array allocations when iterating over the hash
`each_with_object` allocates an array for each kv pair. Switching to the slightly more verbose but less allocatey `each_pair` eliminates array allocations. Eliminating this allocation returns AR objects to have constant array allocations regardless of the number of columns the object has. Here is test code: ```ruby require 'active_record' class Topic < ActiveRecord::Base end 20.times do |i| Process.waitpid fork { ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:' ActiveRecord::Base.connection.instance_eval do create_table(:topics) do |t| t.string :title, limit: 250 t.string :author_name t.string :author_email_address t.string :parent_title t.string :type t.string :group i.times do |j| t.string :"aaa#{j}" end t.timestamps null: true end end ObjectSpace::AllocationTracer.setup(%i{type}) Topic.create title: "aaron" # heat cache result = ObjectSpace::AllocationTracer.trace do 10.times do |i| Topic.create title: "aaron #{i}" end end puts "#{Topic.columns.length},#{(result.find { |k,v| k.first == :T_ARRAY }.last.first / 10)}" } end ``` Before this commit: ``` 9,166 10,167 11,168 12,169 13,170 14,171 15,172 16,173 17,174 18,175 19,176 20,177 21,178 22,179 23,180 24,181 25,182 26,183 27,184 28,185 ``` After: ``` 9,157 10,157 11,157 12,157 13,157 14,157 15,157 16,157 17,157 18,157 19,157 20,157 21,157 22,157 23,157 24,157 25,157 26,157 27,157 28,157 ``` Left side is the number of columns, right is the number of allocations
This commit is contained in:
parent
3b61027092
commit
960de47f0e
1 changed files with 3 additions and 1 deletions
|
@ -39,7 +39,8 @@ class Hash
|
|||
# hash[:a][:c] # => nil
|
||||
# dup[:a][:c] # => "c"
|
||||
def deep_dup
|
||||
each_with_object(dup) do |(key, value), hash|
|
||||
hash = dup
|
||||
each_pair do |key, value|
|
||||
if key.frozen? && ::String === key
|
||||
hash[key] = value.deep_dup
|
||||
else
|
||||
|
@ -47,5 +48,6 @@ class Hash
|
|||
hash[key.deep_dup] = value.deep_dup
|
||||
end
|
||||
end
|
||||
hash
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue