RubySpeed

From APIDesign

Jump to: navigation, search

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:

[埋込みオブジェクト:http://www.youtube.com/v/ufShKmS5Ueo]

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


Truffle gives Ruby the speed it always needed.

AltStyle によって変換されたページ (->オリジナル) /