Android App with the Perl5 to Java compiler

We've had another hackathon at work.

Yati, Bas, Luca and I hacked on the Perlito Perl5-to-Java compiler and also a bit of Perl5-to-JavaScript.

The changes are in GitHub and will be published in the next CPAN release.

The latest cool addition is an Android App example:

specifying primitive data types in Perlito5

I'm trying out this new little benchmark, which imports Java primitive data types into a Perl script:

# misc/benchmark/benchmark_typed_primitive.pl
package long {}
my long $count = 0;
my long $i = 0;
while ( $i < 400 ) {
    my long $j = 0;
    while ( $j < 400 ) {
        my long $k = 0;
        while ( $k < 400 ) {
            $k = $k + 1;
            $count = $count + 1;
        }
        $j = $j + 1;
    }
    $i = $i + 1;
}
my $c = $count;
print "done $c\n";

Comparing with the previous benchmarks:

Plain perl script:

$ time perl misc/benchmark/benchmark_lexical.pl
done 64000000

real    0m4.070s    # base time (1x)
user    0m4.064s
sys 0m0.008s

The same untyped Perl script, running as Perl-in-Java, compilation time excluded:

$ perl perlito5.pl -Isrc5/lib -I. -It -Cjava misc/benchmark/benchmark_lexical.pl > Main.java ; javac Main.java ; time java Main
done 64000000

real    0m0.985s    # 4x faster
user    0m0.626s
sys 0m0.461s

Perl script with primitive types added, running as Perl-in-Java, compilation time excluded:

$ perl perlito5.pl -Isrc5/lib -I. -It -Cjava misc/benchmark/benchmark_typed_primitive.pl  > Main.java ; javac Main.java ; time java Main
done 64000000

real    0m0.102s    # 40x faster
user    0m0.086s
sys 0m0.013s

Just to be sure this is valid Perl:

$ perl -c misc/benchmark/benchmark_typed_primitive.pl
misc/benchmark/benchmark_typed_primitive.pl syntax OK

Compilation time from Perl to Java is:

$ time ( perl perlito5.pl -Isrc5/lib -I. -It -Cjava misc/benchmark/benchmark_typed_primitive.pl  > Main.java ; javac Main.java )

real    0m1.356s
user    0m2.610s
sys 0m0.072s

These command lines run from the root directory of https://github.com/fglock/Perlito checkout; the little benchmark code is at https://github.com/fglock/Perlito/blob/master/misc/benchmark.

Perl5 to Java compiler - using a Perl module from Java

Perlito5 now supports calling Perl subroutines from Java.

For example, a Perl module was compiled to "Main.java", and it can be called using:

 class TestPerl {
    public static void main(String[] args) throws Exception {
        // initialize the Perl module - setup global variables
        // and create the subroutine entries
        Main.init();
        // locate the subroutine main::test
        // and call it with an argument list
        // that is: @res = main::test(123)
        PlObject[] res = Main.apply("main::test", new String[]{ "123" });
        // do something with the results
        for (PlObject s: res) {
            System.out.println("Java result: " + s.toString());
        }
    }
}

Perl5 to Java compiler - first little script

For the first time, Perlito5-Java can now run an unmodified script - "rc-forest-fire" from the perl6-bench project.

I've experimented running the benchmark on the several Perlito5 platforms, and on perl itself:

# Perl5-in-Java - including compilation time
time ( touch Test.class ; rm Test.class ; perl perlito5.pl -Isrc5/lib -Cjava rc-forest-fire.pl > Test.java ; javac Test.java ; java Test 20 20 1000 )
real 6.9s
user 5.7s


# Perl5-in-Java - precompiled
time java Test 20 20 1000
real 5.7s
user 3.7s


# Perl5-in-JS - just-in-time compile
time node perlito5.js -Isrc5/lib rc-forest-fire.pl 20 20 1000
real 5.9s
user 4.8s


# perl
time perl rc-forest-fire.pl 20 20 1000
real 5.3s
user 1.1s

I've tested with javac 1.7.0_79, nodejs 0.10.25, perl 5.20.1 in Ubuntu.

There is a lot to optimize in the Java code generator, and Javascript could do a little better, too. But I'm very happy that the performance is not much worse in the first try!

Perl5 to Java compiler - integrating with java.lang.Thread

Here is another experiment with calling Java libraries from Perlito5-Java; using JVM threads:

package Java::Thread {
    import => "java.lang.Thread"
};

my Java::Thread $thread1 = new Java::Thread(
    sub {
        for my $i (0..10) {
            print "thread 1\n";
            sleep (1);
        }
    }
);
my Java::Thread $thread2 = new Java::Thread(
    sub {
        for my $i (0..10) {
            print "thread 2\n";
            sleep (1);
        }
    }
);

$thread1->start();
$thread2->start();

The source code is at https://github.com/fglock/Perlito/blob/master/misc/Java/TestThread.pl; I've tested with javac 1.7.0_79 in Ubuntu.