nfpyfzyf
nfpyfzyf

Reputation: 2981

Is there a faster way to generate random string in ruby?

  start_time = Time.now
  1000000.times do
        rand(36**1024).to_s(36)
  end
  end_time = Time.now
  puts end_time - start_time

235 seconds.

Is there a faster way to generate random string in ruby?

Upvotes: 1

Views: 1024

Answers (5)

Amol Pujari
Amol Pujari

Reputation: 2349

1.9.3p194 :113 >   
1.9.3p194 :114 >     start_time = Time.now
 => 2012-10-16 19:51:45 +0530 
1.9.3p194 :115 >   1000000.times do
1.9.3p194 :116 >            (Object.new.hash.to_s << Object.new.hash.to_s)[0..35]
1.9.3p194 :117?>     end
 => 1000000 
1.9.3p194 :118 >   end_time = Time.now
 => 2012-10-16 19:51:46 +0530 
1.9.3p194 :119 >   puts end_time - start_time
1.8252512
 => nil 
1.9.3p194 :120 >   

=> 1.8 sec

So in short Object.new.hash.to_s

Upvotes: 0

Oto Brglez
Oto Brglez

Reputation: 4193

If your target system has /dev/urandom you can read random bytes from it. It should be faster. Here is code with benchmark. Some Ruby libs use this approach to generate random things.

Benchmark.bm do|b|

    b.report("Ruby #rand  ") do
      100000.times do
        big_key = rand(36**1024).to_s(36)
      end
    end

    b.report("/dev/urandom") do
      File.open("/dev/urandom",File::RDONLY || File::NONBLOCK || File::NOCTTY) do |f|
        100000.times do
          big_key = f.readpartial(512).unpack("H*")[0]
        end
      end
    end
end

Here you can see benchmark results on 100000, 1024 char long random strings...

       user     system      total        real
Ruby #rand   31.750000   0.080000  31.830000 ( 32.909136)
/dev/urandom  0.810000   5.870000   6.680000 (  6.974276)

Upvotes: 3

slapthelownote
slapthelownote

Reputation: 4279

What about using securerandom?

require 'securerandom'

start_time = Time.now
1000000 .times do
  SecureRandom.base64(1024)
end
end_time = Time.now
puts end_time - start_time

Upvotes: 1

megas
megas

Reputation: 21791

You can shuffle the string to get random strings

array = rand(36**1024).to_s(36).split(//)

start_time = Time.now
1000000.times do
  array.shuffle.join
end
end_time = Time.now
puts end_time - start_time

#=> 126 seconds

Upvotes: 1

Salil
Salil

Reputation: 47482

Don't need to do 36**1024 1000000 times

val=36**1024
1000000.times do
  rand(val).to_s(36)
end

This will definitely save some time

Upvotes: 2

Related Questions