On 10/7/07, Joel VanderWerf <vjoel / path.berkeley.edu> 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/