OCaml vs. SBCL, and various other interpreters
A. Pagaltzis
pagaltzis at gmx.de
Mon Mar 12 09:48:58 EDT 2007
* Kragen Javier Sitaker <kragen at pobox.com> [2007-03-12 08:40]:
> The Microbenchmark (OCaml, Python, Perl, Ruby, Elisp, Tcl)
I thought it would be interesting to know how Parrot fares as a
target.
What I gather is that targetting Parrot is quite nice, with a
bunch of tools to make compiler-writing nice that aren’t exactly
finished, but are shaping up. F.ex you can write the parser in
a large subset of Perl 6 grammars, though it is not finished and
as yet only implements a subset of the subset.
> There's a microbenchmark I like to run on language
> implementations; here's the OCaml version:
>
> let rec fib n = if n < 2 then 1 else fib (n-1) + fib (n-2) in
> print_int (fib 32) ; print_newline() ;;
This is a version written in PIR (Parrot Intermediate
Representation):
.sub fib
.param int n
if n < 2 goto BASE
.local int f2
.local int ret
n -= 1
ret = fib(n)
n -= 1
f2 = fib(n)
ret += f2
.return(ret)
BASE:
.return(1)
.end
.sub main :main
.local int result
result = fib(32)
print result
print "\n"
.end
There may be better ways to write this; it’s the first time I
wrote anything in PIR at all.
Unfortunately, I find it runs significantly slower than the Perl
version regardless of which Parrot “runcore” I use and whether or
not I enable optimisations. The CGP core is the fastest (faster
than the JIT core) at ~8.6s user time on my system whereas the
Perl version runs in ~6.3s (per bash’s `time` builtin).
For completeness, here is the disassembled code of the fib
function:
get_params_pc PMC_CONST(3)
lt_i_ic_ic I2,2,L1
sub_i_ic I2,1
set_args_pc PMC_CONST(3)
set_p_pc P0,PMC_CONST(6)
get_results_pc PMC_CONST(3)
invokecc_p P0
sub_i_ic I2,1
set_args_pc PMC_CONST(3)
set_p_pc P1,PMC_CONST(6)
get_results_pc PMC_CONST(3)
invokecc_p P1
add_i_i I0,I1
set_returns_pc PMC_CONST(3)
returncc
L1: set_returns_pc PMC_CONST(1)
returncc
Of course, since the code was PIR to begin with, the difference
is not that interesting – it’s the same thing, except with the
convenient PIR shortcuts expanded to bare-metal PASM.
The resulting bytecode file is 1088 bytes in size, but looking at
it with a hex viewer, I see there’s a lot of extra file format
glop in there. So I have no idea how much space the actual
bytecode is taking up. However, a file that also contains the
`main` function comes out at 1504 bytes. Even if the presence of
an extra function adds a lot more file format glop, it seems
evident that Parrot bytecode is pretty bulky.
Of course, Parrot is far from finished and the stated performance
goal for Perl 6 is to be at least twice as fast as Perl 5, which
means Parrot is supposed to get a lot faster yet. In particular
I’m pretty sure that little work has gone into the JIT runcore.
I’m not sure what to take away from this.
Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>
More information about the Kragen-discuss
mailing list