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) )

Reply via email to