Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial perf suite

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@4135 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
commit 6c1eac7cbce3cbb0febd2d885651a0ad725b1878 1 parent 325c032
Laurent Sansonetti authored
View
27 perf/boot.rb
@@ -0,0 +1,27 @@
+@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])
+
+@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
View
66 perf/perf_algo.rb
@@ -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 }
View
45 perf/perf_array.rb
@@ -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
View
33 perf/perf_hash.rb
@@ -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
View
64 perf/perf_ivar.rb
@@ -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 }
View
31 perf/perf_loop.rb
@@ -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
View
91 perf/perf_method.rb
@@ -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
View
40 perf/perf_proc.rb
@@ -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
View
48 perf/perf_yield.rb
@@ -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
View
64 perf/run.rb
@@ -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
View
25 rakelib/bench.rake
@@ -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
Please sign in to comment.
Something went wrong with that request. Please try again.