On Mar 8, 2007, at 5:38 PM, Aaron Smith wrote:

We're using uuidtools at work and it is quite possibly the worst code  
I've ever come across. Convoluted, obfuscated for the sake of  
"security" and slow as hell.

% ./blah.rb 100
...
uuidtools-original    0.130000   4.650000   4.780000 (  4.782855)

Yes, 21 uuids per second!

I got a 400x improvement out of it by dropping this into our config/ 
environment.rb:

def UUID.true_random
   (1..8).to_a.map { rand(0x10000) }.pack("n8")
end

% ./blah.rb 100000
./blah.rb:9: warning: redefine true_random
...
uuidtools-modified   11.470000   0.010000  11.480000 ( 11.490444)

> def rand_hex_3(l)
>   "%0#{l}x" % rand(1 << l*4)
> end
>
> def rand_uuid
>   [8,4,4,4,12].map {|n| rand_hex_3(n)}.join('-')
> end

This is clever. I really like it. To take the above solution a couple  
steps further:

% ./blah.rb 1000000
# of iterations = 1000000
                           user     system      total        real
null_time             0.120000   0.000000   0.120000 (  0.116494)
benchmark-1          28.370000   0.050000  28.420000 ( 28.628063) #  
original
benchmark-2          15.320000   0.010000  15.330000 ( 15.339800) #  
inline and remove join
benchmark-3          10.500000   0.000000  10.500000 ( 10.521271) #  
unroll the loop, fully
benchmark-4           8.600000   0.010000   8.610000 (  8.614185) #  
reorg to remove bignum

-----

require 'benchmark'

max = (ARGV.shift || 1_000_000).to_i

def rand_hex_3(l)
   "%0#{l}x" % rand(1 << l*4)
end

def rand_uuid # original
   [8,4,4,4,12].map {|n| rand_hex_3(n)}.join('-')
end

def rand_uuid2 # inline and remove join
   "%08x-%04x-%04x-%04x-%012x" % [8,4,4,4,12].map {|n| rand(1 << n*4) }
end

def rand_uuid3 # unroll the loop
   "%08x-%04x-%04x-%04x-%012x" % [
                                  rand(0x0000100000000),
                                  rand(0x0000000010000),
                                  rand(0x0000000010000),
                                  rand(0x0000000010000),
                                  rand(0x1000000000000),
                                 ]
end

def rand_uuid4 # remove bignums
   "%04x%04x-%04x-%04x-%04x-%06x%06x" % [
                                         rand(0x0010000),
                                         rand(0x0010000),
                                         rand(0x0010000),
                                         rand(0x0010000),
                                         rand(0x0010000),
                                         rand(0x1000000),
                                         rand(0x1000000),
                                        ]
end

puts "# of iterations = #{max}"
Benchmark::bm(20) do |x|
   x.report("null_time") do
     for i in 0..max do
       # do nothing
     end
   end

   x.report("benchmark-1") do
     for i in 0..max do
       rand_uuid
     end
   end

   x.report("benchmark-2") do
     for i in 0..max do
       rand_uuid2
     end
   end

   x.report("benchmark-3") do
     for i in 0..max do
       rand_uuid3
     end
   end

   x.report("benchmark-4") do
     for i in 0..max do
       rand_uuid4
     end
   end
end