ActiveRecord is slow. Hashes are fast.
Introducing the hash_extension gem…
…the first gem associated with my upcoming book, Scaling to Enterprise with Ruby on Rails.
Are you tired of hearing that Ruby is slow? Well, Ruby is slow, in many ways. The trick to a fast site is to not use the parts of Ruby and Rails that are slow in places where performance counts. For example, loading ActiveRecord objects happens to be extremely slow. Something simple like the following statement may take very little database time, but then will spin through the slow process of ActiveRecord object creation.
MyObject.find(:all)
On my dual core macbook pro, on a table with 40k records, this takes 7 seconds of Ruby time. Conversely, the following query, which returns not an array of ActiveRecord (MyObject) objects, but an array of hashes with all the same properties, takes just over 3 seconds:
MyObject.connection.select_all("select * from my_objects")
So if you don’t need the associations or methods that come with the full ActiveRecord version of your data, you can save a lot of Ruby cycles by using hashes instead — over 50% of the overhead. The problem is that the two statements above are not drop-in replacements for each other. Objects follow dot notation (f.attr) whereas hashes follow, well, hash notation (f['attr']). So to switch to the hash result, you would have to update all your code to follow hash notation instead of dot notation, and that’s a pain (not to mention ugly).
hash_extension to the rescue! This gem allows you to access hashes just as you would regular objects. With this gem, the following is possible:
>> hash = Hash.new >> hash.foo = 'bar' >> hash.foo => 'bar'
Now the two statements above are interchangeable. If you have slow pages in need of tuning, and you’re loading lots of object for display purposes only (e.g., you don’t actually need the weight associated with the full objects), this is an easy way to eek out some more performance.You can download the gem here and read more about how to set it up and use it here.

[...] Hashes, Take 2 Posted in plugins, rails by Dan Chak on February 9th, 2008 A few weeks ago, I posted about the release of my gem, hash_extension, which makes Ruby hashes act a little more like plain [...]
I wonder if this has any relationship to HashWithIndifferentAccess [?]
Thanks!
Thanks, very helpful. I was looking for a way of retrieving a single value as an array, and this post put me on the right track.
Old code
Object.find_by_sql(“SELECT id FROM table”).map { |x| x['id'] }
now becomes
Object.connection.select_values(“SELECT id FROM table”)
Big speed up.
The two statements are NOT interchangeable. While you’ll get the same result if your columns are strings, for other types your mileage will vary. This is because column values are type cast before when read as activerecord attributes – something that won’t be done to raw data from the db. This could cause particular problems for Dates and Numeric types.