Mauricio Fern?ndez wrote:
>
> Compare
>     k = 1 until true
>     k                                                  # => nil
> to
>     begin; k = 1 end until true
>     k                                                  # => 1

Oops.. I thought too much like C.  Now I understand that the loop is
called 0 or more times, except in the case of "begin; end while" where
it's 1 or more.  Thank you for teaching me!

> After fixing shuffle3, I get:

I'm getting slightly different results, still better than sort_by{rand}
and better than your new shuffle4, but now only on larger Arrays.  I
wonder too how performance might vary when Enumerable is mixed into ADTs
other than Array.

--Steve

user     system      total        real
shuffle3 (1000)          0.375000   0.000000   0.375000 (  0.375000)
shuffle4 (1000)          0.484000   0.000000   0.484000 (  0.485000)
sort_by{rand} (1000)     0.328000   0.016000   0.344000 (  0.344000)

user     system      total        real
shuffle3 (10000)         3.906000   0.031000   3.937000 (  3.953000)
shuffle4 (10000)         5.531000   0.047000   5.578000 (  5.594000)
sort_by{rand} (10000)    4.672000   0.109000   4.781000 (  4.812000)

user     system      total        real
shuffle3 (100000)       49.703000   0.328000  50.031000 ( 50.280000)
shuffle4 (100000)       71.938000   0.453000  72.391000 ( 73.061000)
sort_by{rand} (100000)  62.000000   0.782000  62.782000 ( 63.451000)

module Enumerable

def shuffle3
h = {}
self.each do |v|
begin
k = rand(1000000000)
end while h.has_key?(k)
h[k] = v
end
h.keys.sort.collect { |k| h[k] }
end

def shuffle4
h = {}
k = rand(1000000000)
self.sort_by{ k = rand(1000000000) while h.has_key?(k); h[k] = k }
end

end