[macruby-changes] [4135] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Sun May 23 19:15:14 PDT 2010


Revision: 4135
          http://trac.macosforge.org/projects/ruby/changeset/4135
Author:   lsansonetti at apple.com
Date:     2010-05-23 19:15:12 -0700 (Sun, 23 May 2010)
Log Message:
-----------
initial perf suite

Modified Paths:
--------------
    MacRuby/trunk/rakelib/bench.rake

Added Paths:
-----------
    MacRuby/trunk/perf/
    MacRuby/trunk/perf/boot.rb
    MacRuby/trunk/perf/perf_algo.rb
    MacRuby/trunk/perf/perf_array.rb
    MacRuby/trunk/perf/perf_hash.rb
    MacRuby/trunk/perf/perf_ivar.rb
    MacRuby/trunk/perf/perf_loop.rb
    MacRuby/trunk/perf/perf_method.rb
    MacRuby/trunk/perf/perf_proc.rb
    MacRuby/trunk/perf/perf_yield.rb
    MacRuby/trunk/perf/run.rb

Added: MacRuby/trunk/perf/boot.rb
===================================================================
--- MacRuby/trunk/perf/boot.rb	                        (rev 0)
+++ MacRuby/trunk/perf/boot.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,27 @@
+ at perf_tests = []
+def perf_test(name, &b)
+  @perf_tests << [name, b]  
+end
+
+if ARGV.size != 2
+  $stderr.puts "Usage: #{__FILE__} <n-iterations> <file.rb>"
+  exit 1
+end
+N = ARGV[0].to_i
+load(ARGV[1])
+
+ at perf_tests.each do |name, proc|
+  times = []
+  N.times do
+    ts = Time.now
+    begin
+      proc.call
+      res = Time.now - ts
+      times << ("%1.6f" % res)
+    rescue
+      times = ['ERROR']
+      break
+    end
+  end
+  puts "#{name}:#{times.join(",")}"
+end

Added: MacRuby/trunk/perf/perf_algo.rb
===================================================================
--- MacRuby/trunk/perf/perf_algo.rb	                        (rev 0)
+++ MacRuby/trunk/perf/perf_algo.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,66 @@
+def fib(n)
+  if n < 3
+    1
+  else
+    fib(n - 1) + fib(n - 2)
+  end
+end
+
+perf_test('fib') { fib(37) }
+
+def tak(x, y, z)
+  unless y < x
+    z
+  else
+    tak(tak(x-1, y, z),
+        tak(y-1, z, x),
+        tak(z-1, x, y))
+  end
+end
+
+perf_test('tak') { tak(18, 9, 0) }
+
+def ack(m, n)
+  if m == 0 then
+    n + 1
+  elsif n == 0 then
+    ack(m - 1, 1)
+  else
+    ack(m - 1, ack(m, n - 1))
+  end
+end
+
+perf_test('ack') { ack(3, 9) }
+
+def mandelbrot_i(x, y)
+  cr = y - 0.5
+  ci = x
+  zi = 0.0
+  zr = 0.0
+  i = 0
+
+  while true
+    i += 1
+    temp = zr * zi
+    zr2 = zr * zr
+    zi2 = zi * zi
+    zr = zr2 - zi2 + cr
+    zi = temp + temp + ci
+    return i if (zi2 + zr2 > 16)
+    return 0 if (i > 1000)
+  end
+end
+
+def mandelbrot
+  y = -39
+  while y < 39
+    x = -39
+    while x < 39
+      i = mandelbrot_i(x / 40.0, y/40.0)
+      x += 1
+    end
+    y += 1
+  end
+end
+
+perf_test('mandelbrot') { mandelbrot }

Added: MacRuby/trunk/perf/perf_array.rb
===================================================================
--- MacRuby/trunk/perf/perf_array.rb	                        (rev 0)
+++ MacRuby/trunk/perf/perf_array.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,45 @@
+perf_test('new') do
+  i = 0
+  while i < 1000000
+    b = [i]
+    c = [i, i]
+    d = [i, i, i]
+    i += 1
+  end
+end
+
+perf_test('<<') do
+  i = 0
+  a = []
+  while i < 1000000
+    a << 1; a << 2; a << 3; a << 4; a << 5
+    a << 5; a << 4; a << 3; a << 2; a << 1
+    a << 1; a << 2; a << 3; a << 4; a << 5
+    a << 5; a << 4; a << 3; a << 2; a << 1
+    i += 1
+  end
+end
+
+perf_test('[]') do
+  i = 0
+  a = [1, 2, 3, 4, 5]
+  while i < 1000000
+    a[0]; a[1]; a[2]; a[3]; a[4]
+    a[0]; a[1]; a[2]; a[3]; a[4]
+    a[0]; a[1]; a[2]; a[3]; a[4]
+    a[0]; a[1]; a[2]; a[3]; a[4]
+    i += 1
+  end
+end
+
+perf_test('[]=') do
+  i = 0
+  a = [1, 2, 3, 4, 5]
+  while i < 1000000
+    a[0] = a[1] = a[2] = a[3] = a[4] = i + 1
+    a[0] = a[1] = a[2] = a[3] = a[4] = i - 1
+    a[0] = a[1] = a[2] = a[3] = a[4] = i + 1
+    a[0] = a[1] = a[2] = a[3] = a[4] = i - 1
+    i += 1
+  end
+end

Added: MacRuby/trunk/perf/perf_hash.rb
===================================================================
--- MacRuby/trunk/perf/perf_hash.rb	                        (rev 0)
+++ MacRuby/trunk/perf/perf_hash.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,33 @@
+perf_test('new') do
+  i = 0
+  while i < 1000000
+    b = {}
+    c = {1 => i}
+    d = {1 => i, 2 => i}
+    i += 1
+  end
+end
+
+perf_test('[]') do
+  i = 0
+  a = {0=>:zero, 1=>:un, 2=>:deux, 3=>:trois, 4=>:quatre}
+  while i < 1000000
+    a[0]; a[1]; a[2]; a[3]; a[4]
+    a[0]; a[1]; a[2]; a[3]; a[4]
+    a[0]; a[1]; a[2]; a[3]; a[4]
+    a[0]; a[1]; a[2]; a[3]; a[4]
+    i += 1
+  end
+end
+
+perf_test('[]=') do
+  i = 0
+  a = {}
+  while i < 1000000
+    a[0] = a[1] = a[2] = a[3] = a[4] = i + 1
+    a[0] = a[1] = a[2] = a[3] = a[4] = i - 1
+    a[0] = a[1] = a[2] = a[3] = a[4] = i + 1
+    a[0] = a[1] = a[2] = a[3] = a[4] = i - 1
+    i += 1
+  end
+end

Added: MacRuby/trunk/perf/perf_ivar.rb
===================================================================
--- MacRuby/trunk/perf/perf_ivar.rb	                        (rev 0)
+++ MacRuby/trunk/perf/perf_ivar.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,64 @@
+class TestIvars
+  def initialize
+    @foo1 = 1; @foo2 = 2; @foo3 = 3; @foo4 = 4; @foo5 = 5
+  end
+
+  def test_get
+    i = 0
+    while i < 2000000
+      @foo1; @foo2; @foo3; @foo4; @foo5; @foo5; @foo4; @foo3; @foo2; @foo1
+      @foo1; @foo2; @foo3; @foo4; @foo5; @foo5; @foo4; @foo3; @foo2; @foo1
+      @foo1; @foo2; @foo3; @foo4; @foo5; @foo5; @foo4; @foo3; @foo2; @foo1
+      @foo1; @foo2; @foo3; @foo4; @foo5; @foo5; @foo4; @foo3; @foo2; @foo1
+      @foo1; @foo2; @foo3; @foo4; @foo5; @foo5; @foo4; @foo3; @foo2; @foo1
+      i += 1
+    end
+  end
+
+  def test_set
+    i = 0
+    while i < 2000000
+      @foo1 = @foo2 = @foo3 = @foo4 = @foo5 = i + 1;
+      @foo1 = @foo2 = @foo3 = @foo4 = @foo5 = i - 1;
+      @foo1 = @foo2 = @foo3 = @foo4 = @foo5 = i + 1;
+      @foo1 = @foo2 = @foo3 = @foo4 = @foo5 = i - 1;
+      i += 1
+    end
+  end
+end
+
+perf_test('get') { TestIvars.new.test_get }
+perf_test('set') { TestIvars.new.test_set }
+
+class TestAttrs
+  attr_accessor :foo1, :foo2, :foo3, :foo4, :foo5
+  def initialize
+    @foo1 = 1; @foo2 = 2; @foo3 = 3; @foo4 = 4; @foo5 = 5
+  end
+
+  def test_reader
+    i = 0
+    while i < 500000
+      foo1; foo2; foo3; foo4; foo5; foo5; foo4; foo3; foo2; foo1
+      foo1; foo2; foo3; foo4; foo5; foo5; foo4; foo3; foo2; foo1
+      foo1; foo2; foo3; foo4; foo5; foo5; foo4; foo3; foo2; foo1
+      foo1; foo2; foo3; foo4; foo5; foo5; foo4; foo3; foo2; foo1
+      foo1; foo2; foo3; foo4; foo5; foo5; foo4; foo3; foo2; foo1
+      i += 1
+    end 
+  end
+
+  def test_writer
+    i = 0
+    while i < 1000000
+      self.foo1 = self.foo2 = self.foo3 = self.foo4 = self.foo5 = i + 1;
+      self.foo1 = self.foo2 = self.foo3 = self.foo4 = self.foo5 = i - 1;
+      self.foo1 = self.foo2 = self.foo3 = self.foo4 = self.foo5 = i + 1;
+      self.foo1 = self.foo2 = self.foo3 = self.foo4 = self.foo5 = i - 1;
+      i += 1
+    end
+  end
+end
+
+perf_test('attr_reader') { TestAttrs.new.test_reader }
+perf_test('attr_writer') { TestAttrs.new.test_writer }

Added: MacRuby/trunk/perf/perf_loop.rb
===================================================================
--- MacRuby/trunk/perf/perf_loop.rb	                        (rev 0)
+++ MacRuby/trunk/perf/perf_loop.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,31 @@
+perf_test('while') do
+  i = 0
+  while i < 10000
+    j = 0
+    while j < 2000
+      j += 1
+    end
+    i += 1
+  end
+end
+
+perf_test('times') do
+  10000.times do
+    2000.times do
+    end
+  end
+end
+
+perf_test('for') do
+  for i in 0..10000
+    for j in 0..2000
+    end
+  end
+end
+
+perf_test('upto') do
+  0.upto(10000) do
+    0.upto(2000) do
+    end
+  end
+end

Added: MacRuby/trunk/perf/perf_method.rb
===================================================================
--- MacRuby/trunk/perf/perf_method.rb	                        (rev 0)
+++ MacRuby/trunk/perf/perf_method.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,91 @@
+class TestMethod
+  def empty_method
+  end
+
+  def noarg_method
+    42
+  end
+
+  def args_method(a, b, c, d, e, f)
+    42
+  end
+
+  def splat_method(*a)
+    42
+  end
+
+  def opt_method(a, b=1, c=2, d=3, e=4)
+    42
+  end
+end
+
+perf_test('empty') do
+  o = TestMethod.new
+  i = 0
+  while i < 1000000
+    o.empty_method; o.empty_method; o.empty_method; o.empty_method;
+    o.empty_method; o.empty_method; o.empty_method; o.empty_method;
+    o.empty_method; o.empty_method; o.empty_method; o.empty_method;
+    o.empty_method; o.empty_method; o.empty_method; o.empty_method;
+    i += 1
+  end
+end
+
+perf_test('noarg') do
+  o = TestMethod.new
+  i = 0
+  while i < 1000000
+    o.noarg_method; o.noarg_method; o.noarg_method; o.noarg_method;
+    o.noarg_method; o.noarg_method; o.noarg_method; o.noarg_method;
+    o.noarg_method; o.noarg_method; o.noarg_method; o.noarg_method;
+    o.noarg_method; o.noarg_method; o.noarg_method; o.noarg_method;
+    i += 1
+  end
+end
+
+perf_test('args') do
+  o = TestMethod.new
+  i = 0
+  while i < 1000000
+    o.args_method(i, 1, i, 2, i, 3); o.args_method(i, 1, i, 2, i, 3)
+    o.args_method(i, 3, i, 2, i, 1); o.args_method(i, 3, i, 2, i, 1)
+    o.args_method(i, 1, i, 2, i, 3); o.args_method(i, 1, i, 2, i, 3)
+    o.args_method(i, 3, i, 2, i, 1); o.args_method(i, 3, i, 2, i, 1) 
+    o.args_method(i, 1, i, 2, i, 3); o.args_method(i, 1, i, 2, i, 3)
+    i += 1
+  end
+end
+
+perf_test('splat') do
+  o = TestMethod.new
+  i = 0
+  while i < 200000
+    o.splat_method(i)
+    o.splat_method(i, i)
+    o.splat_method(i, i, i)
+    o.splat_method(i, i, i, i)
+    o.splat_method(i, i, i, i, i)
+    o.splat_method(i, i, i, i)
+    o.splat_method(i, i, i)
+    o.splat_method(i, i)
+    o.splat_method(i)
+    i += 1
+  end
+end
+
+perf_test('opt') do
+  o = TestMethod.new
+  i = 0
+  while i < 1000000
+    o.opt_method(i)
+    o.opt_method(i, i)
+    o.opt_method(i, i, i)
+    o.opt_method(i, i, i, i)
+    o.opt_method(i, i, i, i, i)
+    o.opt_method(i, i, i, i)
+    o.opt_method(i, i, i)
+    o.opt_method(i, i)
+    o.opt_method(i)
+    i += 1
+  end
+end

Added: MacRuby/trunk/perf/perf_proc.rb
===================================================================
--- MacRuby/trunk/perf/perf_proc.rb	                        (rev 0)
+++ MacRuby/trunk/perf/perf_proc.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,40 @@
+perf_test('call+noarg') do
+  p = Proc.new { 42 }
+  i = 0
+  while i < 1000000
+    p.call; p.call; p.call; p.call; p.call
+    p.call; p.call; p.call; p.call; p.call
+    p.call; p.call; p.call; p.call; p.call
+    p.call; p.call; p.call; p.call; p.call
+    i += 1
+  end
+end
+
+perf_test('call+args') do
+  p = Proc.new { |a, b, c| 42 }
+  i = 0
+  while i < 1000000
+    p.call(i, 2, 3); p.call(1, i, 3); p.call(1, 2, i); p.call(i, i, i)
+    p.call(i, 2, 3); p.call(1, i, 3); p.call(1, 2, i); p.call(i, i, i)
+    p.call(i, 2, 3); p.call(1, i, 3); p.call(1, 2, i); p.call(i, i, i)
+    p.call(i, 2, 3); p.call(1, i, 3); p.call(1, 2, i); p.call(i, i, i)
+    i += 1
+  end
+end
+
+perf_test('call+splat') do
+  p = Proc.new { |*a| 42 }
+  i = 0
+  while i < 100000
+    p.call(i)
+    p.call(i, i)
+    p.call(i, i, i)
+    p.call(i, i, i, i)
+    p.call(i, i, i, i, i)
+    p.call(i, i, i, i)
+    p.call(i, i, i)
+    p.call(i, i)
+    p.call(i)
+    i += 1
+  end
+end

Added: MacRuby/trunk/perf/perf_yield.rb
===================================================================
--- MacRuby/trunk/perf/perf_yield.rb	                        (rev 0)
+++ MacRuby/trunk/perf/perf_yield.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,48 @@
+class TestBlock
+  def yield_noarg
+    i = 0
+    while i < 1000000
+      yield; yield; yield; yield; yield
+      yield; yield; yield; yield; yield
+      yield; yield; yield; yield; yield
+      yield; yield; yield; yield; yield
+      i += 1
+    end
+  end
+
+  def yield_args(n=1000000)
+    i = 0
+    while i < n
+      yield(i, 2, 3); yield(1, i, 3); yield(1, 2, i); yield(i, i, i)
+      yield(i, 2, 3); yield(1, i, 3); yield(1, 2, i); yield(i, i, i)
+      yield(i, 2, 3); yield(1, i, 3); yield(1, 2, i); yield(i, i, i)
+      yield(i, 2, 3); yield(1, i, 3); yield(1, 2, i); yield(i, i, i)
+      i += 1
+    end
+  end
+end
+
+perf_test('noarg') do
+  o = TestBlock.new
+  o.yield_noarg { 42 }
+end
+
+perf_test('same_arity') do
+  o = TestBlock.new
+  o.yield_args { |a, b, c| 42 }
+end
+
+perf_test('less_arity') do
+  o = TestBlock.new
+  o.yield_args(200000) { |a, b| 42 }
+end
+
+perf_test('more_arity') do
+  o = TestBlock.new
+  o.yield_args(200000) { |a, b, c, e| 42 }
+end
+
+perf_test('splat') do
+  o = TestBlock.new
+  o.yield_args(50000) { |*a| 42 }
+end

Added: MacRuby/trunk/perf/run.rb
===================================================================
--- MacRuby/trunk/perf/run.rb	                        (rev 0)
+++ MacRuby/trunk/perf/run.rb	2010-05-24 02:15:12 UTC (rev 4135)
@@ -0,0 +1,64 @@
+#!/usr/bin/ruby
+
+cwd = File.dirname(__FILE__)
+perf_files = []
+rubies = []
+n_iterations = 3
+ARGV.each do |arg|
+  if md = /--rubies=(.*)/.match(arg)
+    rubies = md[1].split(/,/)
+  elsif md = /--iterations=(.*)/.match(arg)
+    n_iterations = md[1].to_i
+    if n_iterations <= 0
+      $stderr.puts "n_iterations must be greater than zero"
+      exit 1
+    end
+  else
+    perf_files << File.join(cwd, "perf_#{arg}.rb")
+  end
+end
+
+if perf_files.empty?
+  perf_files = Dir.glob(File.join(cwd, 'perf_*.rb'))
+end
+
+if rubies.empty?
+  require 'rbconfig'
+  rubies << File.join(RbConfig::CONFIG['bindir'],
+    RbConfig::CONFIG['ruby_install_name'])
+end
+
+rubies_names = rubies.map { |x| `#{x} -v`.scan(/^\w+\s+[^\s]+/)[0] }
+
+print 'Name'.ljust(20)
+rubies_names.each { |x| print x.ljust(20) }
+puts '', '-' * 80
+
+booter = File.join(cwd, 'boot.rb')
+perf_files.each do |file|
+  results = {}
+  rubies.each do |ruby| 
+    output = `#{ruby} #{booter} #{n_iterations} #{file}`.strip
+    output.split(/\n/).each do |line|
+      title, times = line.split(/:/)
+      best = times.split(/,/).min
+      results[title] ||= []
+      results[title] << [ruby, best]
+    end
+  end
+  prefix = File.basename(file).scan(/perf_(\w+)\.rb/)[0][0]
+  results.each do |title, res|
+    print "#{prefix}:#{title}".ljust(20)
+    winner = res.size > 1 ? res.map { |_, best| best }.min : nil
+    res.each do |_, best|
+      s = best.ljust(20)
+      if best == winner
+        s = "\033[32m#{s}\033[0m" # green
+      elsif best == 'ERROR'
+        s = "\033[31m#{s}\033[0m" # red
+      end
+      print s
+    end
+    puts ''
+  end
+end

Modified: MacRuby/trunk/rakelib/bench.rake
===================================================================
--- MacRuby/trunk/rakelib/bench.rake	2010-05-21 22:00:18 UTC (rev 4134)
+++ MacRuby/trunk/rakelib/bench.rake	2010-05-24 02:15:12 UTC (rev 4135)
@@ -1,27 +1,8 @@
 namespace :bench do
-
+  rubies = ENV['rubies']
   desc "Run the regression performance suite"
   task :ci do
-    sh "./miniruby -I./lib bench.rb"
+    rubies = './miniruby' unless rubies
+    sh "/usr/bin/ruby perf/run.rb --rubies=#{rubies}"
   end
-
-  # We cannot run all the benchmarks yet, so we only run a selection for now.
-  YARV_BENCHMARKS = %w{
-    bm_app_answer.rb bm_app_factorial.rb bm_app_fib.rb bm_app_raise.rb
-    bm_app_tak.rb bm_app_tarai.rb bm_app_mergesort.rb bm_loop_times.rb
-    bm_loop_whileloop.rb bm_so_ackermann.rb bm_so_object.rb bm_so_random.rb
-    bm_so_nested_loop.rb bm_vm1_block.rb bm_vm1_const.rb bm_vm1_ivar.rb
-    bm_vm1_ivar_set.rb bm_vm1_ensure.rb bm_vm1_rescue.rb bm_vm1_simplereturn.rb
-    bm_vm2_eval.rb bm_vm2_poly_method.rb bm_vm2_proc.rb bm_vm2_send.rb
-    bm_vm2_method.rb bm_vm2_super.rb bm_vm2_unif1.rb bm_vm2_zsuper.rb
-  } 
-
-  desc "Run the YARV benchmarks"
-  task :yarv do
-    YARV_BENCHMARKS.each do |file|
-      path = File.join('benchmark', file)
-      sh "/usr/bin/ruby b.rb #{path}"
-    end 
-  end
-
 end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100523/2140ec8e/attachment-0001.html>


More information about the macruby-changes mailing list