ActiveRecord#attributes optimization: minimize objects created #6687

merged 1 commit into from Jun 9, 2012


None yet
3 participants

tiegz commented Jun 9, 2012


I propose reverting to the old implementation of ActiveRecord#attributes (changed in c4809d9).


The current way that attributes builds its attributes hash creates (n * 2) + 1 extraneous arrays, where n is the number of attribute keys. Switching back to the old implementation reduces this to 0.

For instance, I have a model with 43 columns; with Memprof (on 1.8.7) we can see that attributes normally creates 87 Arrays because of the map usage:

1.8.7 :010 > Memprof.track { my_record.attributes }
     87 /.../activerecord-3.2.5/lib/active_record/attribute_methods.rb:184:Array
      1 /.../activerecord-3.2.5/lib/active_record/attribute_methods.rb:184:__node__
      1 /.../activerecord-3.2.5/lib/active_record/attribute_methods.rb:184:Hash

Now when we switch back to the original implementation that builds a hash with each (despite having 2 more LOC), we can see the benefit:

1.8.7 :010 > Memprof.track { my_record.attributes }
      1 /.../activerecord-3.2.5/lib/active_record/attribute_methods.rb:184:Hash
      1 /.../activerecord-3.2.5/lib/active_record/attribute_methods.rb:179:Array

I didn't verify the object count in 1.9 myself, but I did a 1.9 GC profile and confirmed that GC did run fewer times overall with this change (over a large sample).


afaik, attributes isn't actually used that often, however serializable_hash uses it. Since serializable_hash would most likely be used in apis where it's common to return lists of many records, it seems worthy of optimizing this method.


josevalim commented Jun 9, 2012

Thanks. I think those appeared when removing the use of inject inside framework. It probably exists in other places.

josevalim merged commit eaeebc2 into rails:3-2-stable Jun 9, 2012


spastorino commented Jun 9, 2012

👍 I've changed master to use each_with_object f9cfe9a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment