Just a little experiment to see how fast I could generate prime numbers in Ruby.
The shackspace public mailing list had a fun little thread where people would implement an algorithm to find primes in the first 2500000 numbers. While I knew that Ruby wouldn't score well on the performance side of things, I thought I could at least give it a try and see how Ruby 1.9.2, Rubinius and JRuby would perform in the end.

Here is the code, a simple sieve of eratosthenes:

def prime_sieve_upto(n)
  all_nums = (0..n).to_a
  all_nums[0] = all_nums[1] = nil
  all_nums.each do |p|
    #jump over nils
    next unless p
    #stop if we're too high already
    break if p * p > n
    #kill all multiples of this number
    (p*p).step(n, p){ |m| all_nums[m] = nil }
  end
  #remove unwanted nils
  all_nums.compact
end

starting = Time.now
amount = 2500000
primes = prime_sieve_upto(amount)
puts "Found #{primes.size} in the numbers from 0 to #{amount} in #{Time.now - starting}s"

On my Macbook Pro (2.6 GHz Core2Duo), the different VMs perform as follows:

ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]:
$ ruby prime_fast.rb
Found 183072 in the numbers from 0 to 2500000 in 3.543216s

rubinius 1.1.1 (1.8.7 release 2010-11-16 JI) [x86_64-apple-darwin10.4.0]
$ rbx prime_fast.rb
Found 183072 in the numbers from 0 to 2500000 in 1.333367s

UPDATE:
rubinius 1.2.0 (1.8.7 release 2010-12-21 JI) [x86_64-apple-darwin10.4.0]
$ rbx prime_fast.rb
Found 183072 in the numbers from 0 to 2500000 in 1.277507s

JRuby 1.5.6:
$ java -Xmx1024m -jar Downloads/jruby-complete-1.5.6.jar prime_fast.rb
Found 183072 in the numbers from 0 to 2500000 in 1.804s

Nice to see rubinius up there :)

Comments