Mauricio FernŠŌdez 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