« Perl6-regex on Perl5-regex | Main | KindaPerl6 released on CPAN »

2007.08.26

Playing with the new "Not Quite Perl"

Today I tried a new product of the Perl 6 project: Not Quite Perl.  "NPQ" is a subset of the Perl 6 syntax. It runs on Parrot.

To put this in context, Pugs has been the most feature-complete implementation of Perl 6, but has suffered from poor performance and lack of Haskell-enabled contributors.

KindaPerl6 currently supports a subset of Perl6, and is executed with Perl5, but also has slow performance now.

"Not Quite Perl" is a similar effort, using Parrot to execute the code. Parrot is expected to be the fastest performing implementation of Perl 6.  Right now "KindaPerl6" and "Not Quite Perl" are developing separately, but there have been discussions to coordinate, according to fglock, a KindaPerl6 contributor.

Here's what I found tried when I tried both technologies today.

First, getting started with the latest parrot release on Ubuntu Feisty was incredibly easy. I ran command to have Ubuntu install the dependencies of parrot:

  sudo apt-get build-dep parrot

From there, I downloaded and unpacked the Parrot 0.4.15 release, since no Ubuntu package had been made for this version yet.

Building parrot was easy:   

  perl Configure.pl
  make

Next, I moved into the "Not Quite Perl" language directory and made sure it was built as well:

  cd languages/nqp
  make

I created my own "nqp" script to make it easier to test Perl 6 code with it.  The script, which I kept in that directory, just looks like this:

#!/bin/sh
../../parrot nqp.pbc

The README there and the tests in "t/" convey what subset of Perl6 is supported so far. It's not a lot, but I believe t he idea is that is enough to to start writing more of Perl 6 using this subset.

The performance is impressive. It executed a basic statement in .3 seconds:

 
  $ time -p echo "say(42);" | ./nqp
  42
  real 0.30
 

The same test using KindaPerl6 took about 15 times longer!

 

  $ time -p echo 42.say | perl -e 'use v6-alpha'
  42
  real 5.66

Update:  As a commenter pointed out, the above syntax is for the "v6", Perl6-on-Perl5, project. The "KindaPerl6" project is available through checking out the "pugs" repository, and provides a major speed improvement through pre-compilation:

 $ time -p echo 42.say | perl kp6-perl5.pl > test.pl
real 0.68
$ time -p perl -Ilib5 test.pl
42
real 0.28

Notice that 'v6-alpha' and KindaPerl6 supported the new method call syntax of "42.say", while NQP required a more conventional subroutine calling syntax "say(42);".

To provide some further context, I timed the same thing with the latest build of Pugs (r17041).  It's performance fell somewhere in between, still close to 10x slower than NQP:

   time -p echo 42.say | pugs
   42
   real 2.02
   

(This result was even less scientific than the others, because I logged into a different, presumably faster, machine to get access to a recent 'pugs' build).

And to put all that into perspective, I tried the same thing with Perl 5.8.8:

  time -p echo 'print "42\n"' | perl
  42
  real 0.01 

The result here was practically instant, or about 30x faster than the Parrot-based NQP test.

Since all of these Perl 6 projects are still in development, I expect there is still a fair amount of room for optimization.

If you want to start playing with Perl 6 syntax now, "Not Quite Perl" and KindaPerl6 may well be easy enough to install and fast enough to please you.

Comments

The KindaPerl6 test has probably to be done this way:

time -p echo "say(42);" | perl kp6-perl5.pl | perl -Ilib

What you currently use is v6.pm, another Perl6-in-Perl5 implementation.

But I cannot exclude the possibility that it is me who is confused by the rich number of Perl6-alike implementations. :-)

Thanks for the tip. That method turned out to be the slowest of all:


$ time -p echo "say(42);" | perl kp6-perl5.pl | perl -Ilib
Can't locate package Value for @Pair::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Pair::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Pair::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Pair::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Capture::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Capture::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Capture::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Signature::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Signature::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @Signature::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Code for @Multi::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
Can't locate package Value for @IO::ISA at /usr/local/share/perl/5.8.8/Moose/Meta/Class.pm line 128.
42
real 7.17

You forgot a -Ilib:

time -p echo "say(42);" | perl kp6-perl5.pl | perl -Ilib5
42
real 0.33
user 0.30
sys 0.02

Mortiz, I had actually included in (it doesn't work at all without it), but I failed to paste it. Somehow, your result is much, much faster. Mine was on a laptop which currently believes it is 732Mhz (although it actually should be able to run faster).

please note that KindaPerl6 supports precompilation:

$ time -p echo "say(42);" | perl kp6-perl5.pl > test.pl
real 0.26
user 0.20
sys 0.04
$ time -p perl -Ilib5 test.pl
42
real 0.08
user 0.07
sys 0.01

fglock, Thanks for the comment. I noticed that the difference in your syntax was specifying "lib5"...not just "lib".

That makes a huge performance difference. :)

I have now updated the article to reflect that KindaPerl6 with pre-compilation is about as fast as NPQ.

Now that kp6 has a CL backend things are going quite a bit faster, at least under SBCL which compiles the resulting code to native machine code.

$ echo 'say 42' | perl kp6-mp6-perl5.pl --lisp > hello.lisp
* munge hello.lisp so that the main code is in a function called "Main"*
$ sbcl --load hello.lisp
* loads of output*
* (sb-ext:save-lisp-and-die "hello.exe" :toplevel (lambda () (Main::Main) 0) :executable t)

$ time ./hello.exe | grep 42
42

real 0m0.063s

$ time perl -I lib-kp6-mp6-p5 hello.pl
42

real 0m0.207s

Post a comment