Optimization Module (ruby-optimizer)

[Extensions] [Index.html] [RAA]
"ruby-optimizer" is an extension module which provides functionarity for optimizing methods and blocks. CVS:

Example 1

This example code shows you tail-recursion and tail 'return' elimination:
require 'optimizer'

def sum_(n, acc)
  if( n > 0 )
    return sum_(n-1, acc + n)
  else
    return acc
  end
end

def sum(n)
  sum_(n, 0)
end

def time(str)
  t1 = Time.now
  begin
    yield
  rescue Exception => e
    print("#{str}: #{e.message}\n")
    #print(e.backtrace.join("\n"),"\n")
    return
  end
  t2 = Time.now
  print("#{str}: #{t2 - t1}\n")
end

time("normal"){
  p sum(ARGV[0].to_i)
}

optimize :sum_
time("optimized"){
  p sum(ARGV[0].to_i)
}
The follows are results:
$ ruby-1.6 sum.rb 1000
500500
normal: 0.014218
500500
optimized: 0.002818

$ ruby-1.6 sum.rb 10000
normal: stack level too deep
50005000
optimized: 0.03651

$ ruby-1.6 sum.rb 100000
normal: stack level too deep
5000050000
optimized: 0.505242

Example 2

The following example shows '!' elimination:
require 'optimizer'

def foo(x)
  if( !(x == 0) )
    x + foo(x - 1)
  else
    x
  end
end

def time(str)
  t1 = Time.now
  begin
    yield
  rescue Exception => e
    print("#{str}: #{e.message}\n")
    #print(e.backtrace.join("\n"),"\n")
    return
  end
  t2 = Time.now
  print("#{str}: #{t2 - t1}\n")
end

time("normal"){
  foo(ARGV[0].to_i)
}

optimize :foo
time("optimized"){
  foo(ARGV[0].to_i)
}
$ ruby-1.6 ex1.rb 1000
normal: 0.01492
optimized: 0.010724

$ ruby-1.6 ex1.rb 2000
normal: 0.030962
optimized: 0.019915

Example 3 (Eratosthenes Benchmark)

The following scripts are available at:
http://www.bagley.org/~doug/shootout/bench/sieve/detail.shtml
I quickly hacked ruby's script as follows:
require "optimizer"
NUM = Integer(ARGV.shift || 1)

def foo()
$count = i = j = 0
flags0 = Array.new(8192,1)

NUM.times do
    $count = 0
    flags = flags0.dup
    for i in 2 .. 8192
        next unless flags[i]
        # remove all multiples of prime: i
        (i+i).step(8192, i) do |j|
            flags[j] = nil
        end
        $count += 1
    end
end
end

optimize :foo
foo()

print "Count: ", $count, "\n"
The above script name is `sieve.ruby.optimized'. I got the following result:
$ ruby-1.6 -v
ruby 1.6.7 (2002-08-01) [i686-linux]
$ time ruby-1.6 sieve.ruby 200
Count: nil

real    0m6.223s
user    0m6.190s
sys     0m0.020s

$ time ruby-1.6 sieve.ruby.optmized 200
Count: 1028

real    0m5.745s
user    0m5.710s
sys     0m0.010s


$ perl -v
This is perl, v5.6.0 built for i586-linux
$ time perl sieve.perl 200
Count: 1028

real    0m4.858s
user    0m4.750s
sys     0m0.010s


$ python
Python 1.5.2 (#1, Dec 10 2001, 00:15:29)
$ time python sieve.python 200
Count: 1028

real    0m4.975s
user    0m4.950s
sys     0m0.000s

$ ocaml 
        Objective Caml version 3.04
$ time ocaml sieve.ocaml 200
Count: 1028

real    0m1.059s
user    0m1.040s
sys     0m0.010s

$ guile -v
Guile 1.4
$ time guile -e main -s sieve.guile 200
Count: 1028

real    0m6.307s
user    0m6.200s
sys     0m0.010s

$ sml
Standard ML of New Jersey, Version 110.0.7
$ sml < sieve.smlnj
$ time sml @SMLload=sieve.x86-linux 200
Count: 1028

real    0m0.182s
user    0m0.180s
sys     0m0.000s


ttate@kt.jaist.ac.jp