RubySpeed
From APIDesign
Ruby was always known to be very slow language. Even when the hype around Rails was on - e.g. around 2006, there was nobody who could make the language fast. The great news is that OracleLabs decided to demonstrate the power of their Truffle framework on Ruby and are working on a fast Ruby implementation. OracleLabs claim that their implementation is ten times faster than the standard Ruby.
I wanted to verify such claim. One thing is being faster in a benchmark, the other thing is to speed up real programs. That is why I decided to write my first Ruby program - the Sieve of Eratosthenes and as following video demonstrates, Truffle based Ruby is really faster:
Is Truffle based Ruby ten times faster? The video shows that standard Ruby can compute about 5000 of prime numbers in 20s on my computer. The Truffle version was able to compute 17000 of primes. For a while I believed that this implies three times speed up. Not bad, but far less than the claim of being ten times faster.
However once, while showing the demo, I forgot to kill the standard Ruby version. After three minutes I noticed that and to my surprise the standard version was still fighting with 15000th prime number - e.g. it takes at least 180s to compute what Truffle Ruby can in 20s. The explanation is easy - computing first thousands of primes is way easier that finding the next thousands ones. The sieve of Eratosthenes algorithm isn't linear. Only comparing the time to compute the same amount of primes makes sense. However such time comparison actually shows ten times speed up!
class Natural def initialize @x = 2 end def next return @x += 1 end end natural = Natural.new class Filter def initialize(number, filter) @number = number @filter = filter end def number @number end def filter @filter end def accept(n) filter = self loop do if (n % filter.number) == 0 return false end filter = filter.filter; break if filter == nil end return true; end end class Primes def initialize(natural) @natural = natural @filter = nil; end def next loop do n = @natural.next if (@filter == nil || @filter.accept(n)) @filter = Filter.new(n, @filter) return n; end end end end primes = Primes.new(natural) puts "Press Ctrl-D to start..." $stdin.read start = Time.now cnt = 0 res = "" puts "Working..." loop do p = primes.next res << "#{p}\n" cnt += 1 if cnt % 1000 == 0 puts res puts "Computed #{cnt} primes in #{Time.now - start} s" res = "" end end