In one of my applications, I have a lot of queries that return just an id and a content column for each of the rows in the result. e.g. +----+---------+ | id | content | +----+---------+ | 35 + apple | | 79 + pear | +----+---------+ I''d like to be able to access the object returned by result = Food.find(:all) like result[79] = "pear" I''m trying to minimize the time needed to convert the Food object into this hash. Does anyone have an idea which method might be the fastest? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi -- On Thu, 13 Mar 2008, Devin Mccabe wrote:> > In one of my applications, I have a lot of queries that return just an > id and a content column for each of the rows in the result. e.g. > > +----+---------+ > | id | content | > +----+---------+ > | 35 + apple | > | 79 + pear | > +----+---------+ > > I''d like to be able to access the object returned by > result = Food.find(:all) > like > result[79] = "pear" > > I''m trying to minimize the time needed to convert the Food object into > this hash. Does anyone have an idea which method might be the fastest?You may already have one that''s faster than either of these, but for what it''s worth, it looks like this: a = Food.find(:all, :select => "id, content") result = Hash[*a.map {|e| e.attributes.values}.flatten] is much slower than: a = Food.find(:all, :select => "id, content") result = {} a.map {|e| result[e.id] = e.content } Much slower, as in: user system total real Hash 5.820000 0.030000 5.850000 ( 5.849504) map 0.760000 0.000000 0.760000 ( 0.763521) I think the first is cooler, but coolth sometimes comes at a price :-) David -- Upcoming Rails training from David A. Black and Ruby Power and Light: ADVANCING WITH RAILS, April 14-17 2008, New York City CORE RAILS, June 24-27 2008, London (Skills Matter) See http://www.rubypal.com for details. Berlin dates coming soon! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Mar 12, 10:45 pm, Devin Mccabe <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> I''m trying to minimize the time needed to convert the Food object into > this hash. Does anyone have an idea which method might be the fastest?If you really want to be fast you might avoid the object instantiation and go with direct SQL. But if you don''t have to be super fast I would keep it readable and just do something like this: food_lookup_table = Food.find(:all).inject({}) {|m,f| m[f.id] f.content; m} Of course over time I have crafted a nice Enumerable#to_h method to handle many of these common cases so the above translated to: food_lookup_table = Food.find(:all).to_h :id, :content If you are interested in my method I have pasted it below. It does a lot more than just the above because I have continued to enhance it over time. module Enumerable # Abstracts the process of converting a list to a hash. In your block # just return a array where the first value is the key and the second # value is the value. If the key and value are simple method calls # you can just pass in the symbols as arguments. Finally if you just # return a single value (not an array) then it will assume that is # the value and use the enumerable item as the key. If the value is # a simple method and you want to assume the key you can just pass # the value method in. # # Person.find(:all).to_h {|p| [p.id, p.name]} # Person.find(:all).to_h :id, :name # (params.keys - ignore).to_h {|k| params[k]} # Person.find(:all).to_h(:name).invert # # Inspired from http://www.chadfowsler.com/2007/8/3/enumerable-injecting # but simplified and then made complicated again. :) def to_h(key=nil, value=nil, &block) block = lambda do |i| if value.nil? i.send key else [i.send(key), i.send(value)] end end unless block_given? inject Hash.new do |map, i| k, v = *[block.call(i)].flatten if v.nil? v = k k = i end map[k] = v map end end end Eric --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
@David, I don''t have your datasest... how does the following compare? a = Food.find(:all, :select=>''id, content'') a.inject({}){|collection, item| collection.merge item;id=>item.content} Perhaps as a result of all the PED talk in baseball, I''ve become quite a fan of inject-ing things. :-) On Mar 12, 11:17 pm, "David A. Black" <dbl...-0o/XNnkTkwhBDgjK7y7TUQ@public.gmane.org> wrote:> Hi -- > > > > On Thu, 13 Mar 2008, Devin Mccabe wrote: > > > In one of my applications, I have a lot of queries that return just an > > id and a content column for each of the rows in the result. e.g. > > > +----+---------+ > > | id | content | > > +----+---------+ > > | 35 + apple | > > | 79 + pear | > > +----+---------+ > > > I''d like to be able to access the object returned by > > result = Food.find(:all) > > like > > result[79] = "pear" > > > I''m trying to minimize the time needed to convert the Food object into > > this hash. Does anyone have an idea which method might be the fastest? > > You may already have one that''s faster than either of these, but for > what it''s worth, it looks like this: > > a = Food.find(:all, :select => "id, content") > result = Hash[*a.map {|e| e.attributes.values}.flatten] > > is much slower than: > > a = Food.find(:all, :select => "id, content") > result = {} > a.map {|e| result[e.id] = e.content } > > Much slower, as in: > > user system total real > Hash 5.820000 0.030000 5.850000 ( 5.849504) > map 0.760000 0.000000 0.760000 ( 0.763521) > > I think the first is cooler, but coolth sometimes comes at a price :-) > > David > > -- > Upcoming Rails training from David A. Black and Ruby Power and Light: > ADVANCING WITH RAILS, April 14-17 2008, New York City > CORE RAILS, June 24-27 2008, London (Skills Matter) > Seehttp://www.rubypal.comfor details. Berlin dates coming soon!--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi -- On Thu, 13 Mar 2008, AndyV wrote:> > @David, > > I don''t have your datasest... how does the following compare? > > a = Food.find(:all, :select=>''id, content'') > a.inject({}){|collection, item| collection.merge > item;id=>item.content} > > Perhaps as a result of all the PED talk in baseball, I''ve become quite > a fan of inject-ing things. :-)Yes, that runs faster, though the code needs some massaging to run: a.inject({}) {|collection, item| collection.merge(item.id => item.year) } David -- Upcoming Rails training from David A. Black and Ruby Power and Light: ADVANCING WITH RAILS, April 14-17 2008, New York City CORE RAILS, June 24-27 2008, London (Skills Matter) See http://www.rubypal.com for details. Berlin dates coming soon! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Oops. Lazy ring finger. :-) On Mar 13, 5:14 pm, "David A. Black" <dbl...-0o/XNnkTkwhBDgjK7y7TUQ@public.gmane.org> wrote:> Hi -- > > On Thu, 13 Mar 2008, AndyV wrote: > > > @David, > > > I don''t have your datasest... how does the following compare? > > > a = Food.find(:all, :select=>''id, content'') > > a.inject({}){|collection, item| collection.merge > > item;id=>item.content} > > > Perhaps as a result of all the PED talk in baseball, I''ve become quite > > a fan of inject-ing things. :-) > > Yes, that runs faster, though the code needs some massaging to run: > > a.inject({}) {|collection, item| > collection.merge(item.id => item.year) > } > > David > > -- > Upcoming Rails training from David A. Black and Ruby Power and Light: > ADVANCING WITH RAILS, April 14-17 2008, New York City > CORE RAILS, June 24-27 2008, London (Skills Matter) > Seehttp://www.rubypal.comfor details. Berlin dates coming soon!--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---