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