On Wed, Nov 17, 2004 at 10:03:14PM +0100, Leopold Toetsch wrote:
> As already stated, I don't consider these as either light-weight nor 
> faster. Here is a benchmark.
> 
> Below are 2 version of a recursive factorial program. fact(100) is 
> calculated 1000 times:
> 
> PIR           1.1 s
> bsr/ret       2.4 s
> PIR/tailcall  0.2s
> 
> Unoptimized Parrot, default i.e. slow run core.

Sure, but the bsr/ret in your version is making lots of saveall calls 
that I'd be avoiding.  Also, this code is saving pmc's (big ones at 
that) whereas I'll generally be pushing a few ints and maybe a string 
onto the stack.  So, rewriting the above for ints instead of PerlInts, 
changing the multiply op to add to stay within the range of ints, and 
removing the unneeded saves/restores for things that are being passed 
as parameters anyway (and doubling the count save/restore to make it 
somewhat closer to what I'd expect...):

[EMAIL PROTECTED] pmichaud]$ parrot pmfact.imc     #PIR
500500
5.819842
[EMAIL PROTECTED] pmichaud]$ parrot pmfactbsr.imc  #bsr/ret
500500
2.010935

Please keep in mind that I'm a newcomer to Parrot, so it's entirely
possible that I'm made some invalid assumptions in my code that skew
these results (and I'll freely admit them if pointed out).
And I will admit that the PIR code is still impressive speed-wise
relative to what it is doing, but it's hard to ignore a 60% improvement.

Pm
.sub optc @IMMEDIATE
    # TODO turn on -Oc
    # print "optc\n"
.end
.sub _main @MAIN
    .param pmc argv
    .local int count, product
    .local float start, end
    count = 1000
    .local int argc
    argc = elements argv
    if argc < 2 goto def
    $S0 = argv[1]
    count = $S0
def:
    .local int i
    i = 0
    start = time
    .local int n
loop:
    n = count
    product = 1
    product = _fact(product, n)
    inc i
    if i < 1000 goto loop
    end = time
    end -= start
     print product
     print "\n"
    print end
    print "\n"
.end
.sub _fact
   .param int product
   .param int count
   if count > 1 goto recurs
   .return (product)
recurs:
   product += count
   dec count
   product = _fact(product, count)
   .return (product)
.end

.sub _main @MAIN
    .param pmc argv
    .local int count, product
    .local float start, end
    count = 1000
    .local int argc
    argc = elements argv
    if argc < 2 goto def
    $S0 = argv[1]
    count = $S0
def:
    .local int i
    i = 0
    start = time
    .local int n
loop:
    n = count
    product = 1
    save count
    bsr fact
    restore count
    inc i
    if i < 1000 goto loop
    end = time
    end -= start
    print product
    print "\n"
    print end
    print "\n"
    goto ex

fact:
    if count > 1 goto recurse
    ret
recurse:
    product += count
    dec count
    save count
    save count
    bsr fact
    restore count
    restore count
    ret

ex:
.end
    

Reply via email to