From: Sam Smoot Date: 2007-01-17T13:55:10+09:00 Subject: Re: Can anyone try to solve this problems? Daniel Martin wrote: > Why build up a separate hash structure? It's simpler to my eyes. It's also (admittedly unintuitively) faster though. Here's a quick test with your version, my original, and another going off your idea, but I tried to simplify it a bit: > #!/opt/local/bin/ruby > class Symbol > def to_proc > lambda { |x| x.send(self) } > end > end > > module Enumerable > def max_by1 > last_value = nil > > inject do |max_item, item| > current_value = yield item > if last_value.nil? || current_value > last_value > last_value = current_value > item > else > max_item > end > end > end > > def max_by2 > pairs = inject({}) do |hash, obj| > hash[yield obj] = obj; hash > end > pairs[pairs.keys.max] > end > > def max_by3 > max_value = nil > max_item = nil > > each do |item| > value = yield(item) > max_item, max_value = item, value if max_value.nil? || value > max_value > end > > max_item > end > end > > a = %w{ one two three four } > > 16.times do |i| > a = a + a > end > > puts "a.size => #{a.size}" > require 'benchmark' > > Benchmark::bm do |bm| > bm.report { puts a.max_by1 &:size } > bm.report { puts a.max_by2 &:size } > bm.report { puts a.max_by3 &:size } > end I couldn't tell you why the 3rd is so much faster than the first. Just goes to prove the old programming adage though: "Optimizing before Profiling is a waste of time." Not that this counts as serious profiling of course. :-)