Looks like it may be time to investigate things further. A method
cache is probably the next thing in line to do.
I didn't see a benchmark for method lookup and calling, so I modified
a copy of fib to bounce back and forth between a class and its parent.
Patch attached.
My optimized parrot ran it a factor of 2x slower than my perls, 3x than
my ruby, with my pythons in between. Unoptimized was just a bit worse.
(However, caveat, my optimized parrot doesn't pass make test.)
A quick look at a profile (*** always a dangerous practice ***)
seemed _vaguely_ like half method calls, and half memory management.
With method calls split between lookup (spent in hash), and creating
return continuation pmcs.
I thought it curious 1/10+ of time seemed spent under Parrot_set_s_sc,
when there's nary a string to be seen. Method names?
I wonder if find_global might be happier with a simpler hash than hash.
Especially if this is where the string copies are coming from.
The 1/4 time spent creating continuations also seemed notable.
So a quick, and thus no doubt wrong, interpretation might be that method
calling is leaning hard on memory, which is then leaning hard on time.
Maybe.
Mitchell
--- nonexistent Tue Mar 16 22:18:01 2004
+++ ./examples/benchmarks/method1.rb Tue Mar 16 18:51:38 2004
@@ -0,0 +1,25 @@
+#! ruby
+
+class A
+ def fib(n)
+ return n if (n < 2)
+ return fibA(n - 1) + fibB(n - 2)
+ end
+ def fibA(n)
+ return n if (n < 2)
+ return fib(n - 1) + fibB(n - 2)
+ end
+end
+
+class B < A
+ def fibB(n)
+ return n if (n < 2)
+ return fib(n - 1) + fibA(n - 2)
+ end
+end
+
+b = B.new
+
+N = Integer( ARGV.shift || 24 )
+
+puts "fib(#{N}) = #{ b.fib(N) }"
--- nonexistent Tue Mar 16 22:18:01 2004
+++ ./examples/benchmarks/method1.pl Tue Mar 16 18:41:47 2004
@@ -0,0 +1,33 @@
+use strict;
+
+package A;
+sub fib {
+ my $self = shift;
+ my $n = shift;
+ return $n if ($n < 2);
+ return $self->fibA($n-1) + $self->fibB($n-2);
+}
+sub fibA {
+ my $self = shift;
+ my $n = shift;
+ return $n if ($n < 2);
+ return $self->fib($n-1) + $self->fibB($n-2);
+}
+package B;
[EMAIL PROTECTED]::ISA=qw(A);
+sub new { bless {}, $_[0] }
+sub fibB {
+ my $self = shift;
+ my $n = shift;
+ return $n if ($n < 2);
+ return $self->fib($n-1) + $self->fibA($n-2);
+}
+
+package main;
+
+my $N = shift || 24;
+
+my $b = B->new();
+
+print "fib($N) = ", $b->fib($N), "\n";
+
--- nonexistent Tue Mar 16 22:18:01 2004
+++ ./examples/benchmarks/method1.imc Tue Mar 16 19:14:44 2004
@@ -0,0 +1,106 @@
+
+.pcc_sub _main prototyped
+ .param pmc argv
+ .sym int argc
+ argc = argv
+ .sym int N
+ N = 24
+ if argc <= 1 goto noarg
+ $S0 = argv[1]
+ N = $S0
+noarg:
+ .sym float start
+ time start
+
+ .local pmc A
+ .local pmc B
+ .local pmc b
+
+ newclass A, "A"
+ subclass B, A, "B"
+
+ find_type I0, "B"
+ new b, I0
+
+ .sym int r
+ r = b.fib(N)
+
+ .sym float fin
+ time fin
+ print "fib("
+ print N
+ print ") = "
+ print r
+ print " "
+ sub fin, start
+ print fin
+ print "s\n"
+ end
+.end
+
+.namespace ["A"]
+
+.sub fib method
+ .param int n
+ if n >= 2 goto rec
+ .pcc_begin_return
+ .return n
+ .pcc_end_return
+rec:
+ .sym int n1
+ .sym int n2
+ .sym int r1
+ .sym int r2
+ n1 = n - 1
+ n2 = n - 2
+ r1 = self.fibA(n1)
+ r2 = self.fibB(n2)
+ n = r1 + r2
+ .pcc_begin_return
+ .return n
+ .pcc_end_return
+.end
+
+.sub fibA method
+ .param int n
+ if n >= 2 goto rec
+ .pcc_begin_return
+ .return n
+ .pcc_end_return
+rec:
+ .sym int n1
+ .sym int n2
+ .sym int r1
+ .sym int r2
+ n1 = n - 1
+ n2 = n - 2
+ r1 = self.fib(n1)
+ r2 = self.fibB(n2)
+ n = r1 + r2
+ .pcc_begin_return
+ .return n
+ .pcc_end_return
+.end
+
+.namespace ["B"]
+
+.sub fibB method
+ .param int n
+ if n >= 2 goto rec
+ .pcc_begin_return
+ .return n
+ .pcc_end_return
+rec:
+ .sym int n1
+ .sym int n2
+ .sym int r1
+ .sym int r2
+ n1 = n - 1
+ n2 = n - 2
+ r1 = self.fib(n1)
+ r2 = self.fibA(n2)
+ n = r1 + r2
+ .pcc_begin_return
+ .return n
+ .pcc_end_return
+.end
--- nonexistent Tue Mar 16 22:18:01 2004
+++ ./examples/benchmarks/method1.py Tue Mar 16 18:46:00 2004
@@ -0,0 +1,27 @@
+#! python
+
+import sys
+
+class A:
+ def fib(self,n):
+ if (n < 2):
+ return(n)
+ return( self.fibA(n-2) + self.fibB(n-1) )
+ def fibA(self,n):
+ if (n < 2):
+ return(n)
+ return( self.fib(n-2) + self.fibB(n-1) )
+
+
+class B (A):
+ def fibB(self,n):
+ if (n < 2):
+ return(n)
+ return( self.fib(n-2) + self.fibA(n-1) )
+
+
+N = int(len(sys.argv) == 2 and sys.argv[1] or 24)
+
+b = B()
+
+print "fib(%d) = %d" %( N, b.fib(N) )