Dan Chak’s Blog

Speeding up ActiveRecord with Hashes, Take 2

Posted in plugins, rails by Dan Chak on February 9, 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 old objects. That’s a good thing, because ActiveRecord requests that return hashes instead of full-blown ActiveRecord objects are about 50% faster. 50% is not a performance tweak — it’s basically the best thing that’s ever happened to ActiveRecord.

In version 0.0.1, the only way to get back hashes from ActiveRecord for use with hash_extension was to use select_all:

Foo.connection.select_all("select * from foo")

In the docs for hash_extension I put out a call for someone to extend ActiveRecord itself to return hashes from more natural, ActiveRecord-esque methods. Elliot Laster answered that call, and now, in version 0.0.2, find_as_hashes and find_by_sql_as_hashes are now available:

Foo.find_as_hashes(:all)
Foo.find_as_hashes(:first)
Foo.find_as_hashes(:all, :conditions => "bar = 'baz'")
Foo.find_by_sql_as_hashes("complex sql goes here")

To learn more about the gem and to download, go here.

Tagged with: , , ,

8 Responses

Subscribe to comments with RSS.

  1. roger said, on April 29, 2008 at 9:32 pm

    I noticed that http://pennysmalls.com/ also has a gem that, when used in conjunction with this one, results in even more memory speed up. Nice :)
    -R

  2. roger said, on April 29, 2008 at 10:01 pm

    You may want to advertise your gem on rails talk :)

  3. roger said, on April 30, 2008 at 7:14 am

    A nicety is that you’re able to ‘intertwine’ this with AR itself.

    a = School.find(:first)
    a.programs.find_as_hashes(:all) # this one. Ahh
    Thank you!
    -R

  4. roger said, on May 1, 2008 at 4:39 pm

    Perhaps another nicety would be something like
    a = Model.find_as_hashes(:all)
    a[22].to_ar # creates and instantiates an ar for this row [costly], so you can use its nice functions for special cases.
    Thoughts?
    -R

  5. Dan Chak said, on May 1, 2008 at 4:59 pm

    I think by that time you’ve lost the information regarding what the class was, so it could be difficult to do something like this without adding overhead to the original find_as_hashes call.

    In general I think this is only useful for situations where you don’t need the AR layer, like in queries aimed at display as opposed to queries aimed at database modification. I think the general solution is “Make ActiveRecord more efficient,” which someone did do for the 1.2.x series, but the patches were lost on the way to 2.0.

  6. roger faith promoting stories said, on August 2, 2008 at 6:31 am

    as mentioned somewhere else, I wonder if this in combination with http://railsexpress.de/blog/articles/2006/10/05/make-ruby-mysql-create-less-garbage would be…even better :)
    Just a thought.
    -R

  7. roger said, on August 28, 2008 at 10:54 pm

    Latest thought: combine all_hashes with a klass.allocate and ‘circumvent’ AR to create AR objects–but in a far far faster way. Then do it “always” if possible [reverting to old school if impossible]. Replace AR.find with it. That would be fast.

    And then do the heavy lifting in C, possibly intertwining it with mysql_use_result and mysql_fetch_row.
    Wish me luck!
    -=R


Leave a Reply