On Tue, 3 Apr 2007, David Flanagan wrote:

> I agree that the current documentation and implementation are not
> inconsistent.  Implicit in my question was a concern about efficiency. I have
        [...]
Given it's importance in sorting, optimising comparison may not be 
premature.
> 
> A simple benchmark is included.  It shows that it is about 25% faster to write

I've taken this code and walloped it with something blunt (my head?).
See below.

I was interested to see the results:

brains hgs 60 %> ruby comparisons.rb
Rehearsal --------------------------------------------
Fast      13.300000   0.010000  13.310000 ( 13.653813)
Slow      16.240000   0.000000  16.240000 ( 16.398890)
Dunno     14.260000   0.000000  14.260000 ( 14.678848)
TryThis   13.650000   0.000000  13.650000 ( 13.699857)
HowAbout  19.110000   0.010000  19.120000 ( 19.548156)
Maybe     17.660000   0.010000  17.670000 ( 18.079618)
---------------------------------- total: 94.250000sec

               user     system      total        real
Fast      13.520000   0.010000  13.530000 ( 21.544449)
Slow      15.920000   0.000000  15.920000 ( 16.322397)
Dunno     14.160000   0.000000  14.160000 ( 14.276026)
TryThis   13.680000   0.000000  13.680000 ( 14.103555)
HowAbout  19.220000   0.000000  19.220000 ( 19.557289)
Maybe     17.670000   0.000000  17.670000 ( 17.727069)
brains hgs 61 %>


These suggest that implementing <=> just with <=> is about as
quick as one can get.  I think a sgn function implemented in 
C would be good, though.  If only so we could test that approach.
> 
> ------------------------------------------------
> Here are the benchmark results on my aging Linux system:
> 
> Rehearsal ----------------------------------------
> Fast   4.390000   0.000000   4.390000 (  4.403584)
> Slow   5.640000   0.020000   5.660000 (  5.657363)
> ------------------------------ total: 10.050000sec
> 
>            user     system      total        real
> Fast   4.020000   0.000000   4.020000 (  4.025188)
> Slow   5.500000   0.000000   5.500000 (  5.503963)
> 

My machine is beginning to look seriously old.
> 
> 
        Hugh


class Slow
  def initialize(x)
    @x = x
  end

  def value
    @x
  end

  def <=>(other)
    y = other.value
    if @x < y
      -1
    elsif @x > y
      1
    else
      0
    end
  end
end

class Fast
  def initialize(x)
    @x = x
  end

  def value
    @x
  end

  def <=>(other)
    other.value - @x
  end
end

class Dunno < Fast
  def <=>(other)
    y = other.value
    y <=> @x
  end
end

class TryThis < Fast
  def <=>(other)
    other.value <=> @x
  end
end

class HowAbout < Fast
  def <=>(other)
    result = other.value - @x
    return -1 if result < 0
    return 0 if result.zero?
    return 1
  end
end

class Maybe < Fast
  def <=>(other)
    result = other.value - @x
    return result <=> 0
  end
end


require 'benchmark'
include Benchmark

bmbm(2) do |x|
  # Need this here or the second time round they'll be sorted.
  f = []
  s = []
  d = []
  t = []
  h = []
  m = []

  100000.times do
    r = rand(100000)
    f << Fast.new(r)
    s << Slow.new(r)
    d << Dunno.new(r)
    t << TryThis.new(r)
    h << HowAbout.new(r)
    m << Maybe.new(r)
  end

  x.report("Fast") { f.sort }
  x.report("Slow") { s.sort }
  x.report("Dunno") { d.sort }
  x.report("TryThis") { t.sort }
  x.report("HowAbout") { h.sort }
  x.report("Maybe") { m.sort }
end