From: Rick DeNatale Date: 2007-10-08T06:20:34+09:00 Subject: Re: #sort_by and #sort_obj On 10/7/07, Joel VanderWerf wrote: > Eric Hodel wrote: > > somethings.sort_by { |s| s.sort_obj } > > Since this is more efficient than #sort, maybe the implementation of > #sort should first try to do this, and only if that fails (#sort_obj not > defined, or two sort_obj not comparable), revert to the normal <=> > algorithm. Yes, but sort_by is not always more efficient than sort: $ qri sort_by ----------------------------------------------------- Enumerable#sort_by enum.sort_by {| obj | block } => array ------------------------------------------------------------------------ Sorts enum using a set of keys generated by mapping the values in enum through the given block. %w{ apple pear fig }.sort_by {|word| word.length} #=> ["fig", "pear", "apple"] The current implementation of sort_by generates an array of tuples containing the original collection element and the mapped value. This makes sort_by fairly expensive when the keysets are simple require 'benchmark' include Benchmark a = (1..100000).map {rand(100000)} bm(10) do |b| b.report("Sort") { a.sort } b.report("Sort by") { a.sort_by {|a| a} } end produces: user system total real Sort 0.180000 0.000000 0.180000 ( 0.175469) Sort by 1.980000 0.040000 2.020000 ( 2.013586) Also adding the startup overhead to check for an implementation of sort_obj is an expense. There's also the issue that you really need to check if ALL of the elements being sorted respond to sort_obj. It seems better to me to either reserve this technique as a pattern, or at most add a new sort_by_sort_obj method or the like, and leave sort as it is. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/