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