Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

performance of perl vs java

by Anonymous Monk
on Oct 27, 2011 at 16:01 UTC ( #934178=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am beginning to learn some Perl, and I decided to do a little performance comparison between Java and Perl. I took an example from Sam's Teach Yourself (Listing 3.3) which is the classic 'print the primes' program, and I modified it to display the execution time. Then I made a few more changes so it would run as a Java program. To my surprise, Java was MUCH faster than Perl. In Java, to print out the first 100 prime numbers took only milliseconds, but the same program in Perl took 10 seconds. HUGE difference! I thought that Perl would be much faster, but I guess I was wrong. Can anyone provide some feedback on this? Here is the code for Perl:
$maxprimes=100; $value=1; $count=0; $start=time(); print "Printing the first $maxprimes numbers that are prime... \n" +; while ($count < $maxprimes) { $value++; $composite=0;#false OUTER: for ($i=2; $i < $value; $i++) { INNER: for ($j=$i; $j<$value; $j++) { if (($j*$i) == $value) { $composite=1;#true last OUTER; } } } if (! $composite) { $count++; print "$value is prime\n"; } } $time = (time() - $start); print "Took $time seconds.";

And here is the listing for Java:

public class Listing3_3 { public static void main(String[] args) { int $maxprimes=100; int $value=1; int $count=0; long $start = System.currentTimeMillis(); System.out.println("Printing the first " + $maxprimes + " +numbers that are prime... \n"); while ($count < $maxprimes) { $value++; int $composite=0;//false OUTER: for (int $i=2; $i < $value; $i++) { INNER: for (int $j=$i; $j<$value; $j++) { if (($j*$i) == $value) { $composite=1;//true break OUTER; } } } if ($composite == 1) { $count++; System.out.println($value + " is prime\n"); } } long $time = (System.currentTimeMillis() - $start) / 1000; + System.out.println("Took " + $time + " seconds"); } }

Comment on performance of perl vs java
Select or Download Code
Re: performance of perl vs java
by moritz (Cardinal) on Oct 27, 2011 at 16:09 UTC

    Java has a pretty good JIT compiler, and if you write code that plays to Java's strengths, it's faster than Perl code that plays to Java's strengths.

    Perl's strengths (performance wise) are for example the regex engine, and situations where the polymorphic nature of Perl 5's scalars is actually used.

    See also: Perl slower than java.

Re: performance of perl vs java
by runrig (Abbot) on Oct 27, 2011 at 16:15 UTC
    Perl is more convenient to program in, but not necessarily faster (well, programming time is usually faster, runtime may be slower). Although I did get the perl version runtime down from about 10 seconds to a couple of seconds by just making the program a bit more perlish:
    use strict; use warnings; my $maxprimes=100; my $value=1; my $count=0; my $start=time(); print "Printing the first $maxprimes numbers that are prime... \n"; while ($count < $maxprimes) { my $v = $value++; my $composite; OUTER: for my $i (2..$v) { INNER: for my $j ($i..$v) { if (($j*$i) == $value) { $composite=1;#true last OUTER; } } } if (! $composite) { $count++; print "$value is prime\n"; } } my $time = (time() - $start); print "Took $time seconds.\n";
Re: performance of perl vs java
by Lotus1 (Chaplain) on Oct 27, 2011 at 17:26 UTC

    I noticed that the comparison is not the same between the two versions.

  • Java version:   if ($composite == 1)
  • Perl version:   if (! $composite)
  • The Perl version is finding primes where the Java version is just printing the first 100 numbers that come along. That is why it was so fast.

    #!/usr/bin/perl use warnings; use strict; my $maxprimes=100; my $value=1; my $count=0; my $start=time(); print "Printing the first $maxprimes numbers that are prime... \n"; while ($count < $maxprimes) { $value++; my $composite=0;#false OUTER: for (my $i=2; $i < $value; $i++) { INNER: for (my $j=$i; $j<$value; $j++) { if (($j*$i) == $value) { $composite=1;#true last OUTER; } } } # if (! $composite) #this works if ($composite == 1) #from the java section, doesn't work { $count++; print "$value is prime\n"; } } my $time = (time() - $start); print "Took $time seconds.";

    Update: It looks like it prints the non-prime numbers.

    Printing the first 100 numbers that are prime... 4 is prime 6 is prime 8 is prime 9 is prime 10 is prime 12 is prime 14 is prime 15 is prime . . . 128 is prime 129 is prime 130 is prime 132 is prime 133 is prime Took 0 seconds.
Re: performance of perl vs java
by Anonymous Monk on Oct 27, 2011 at 20:27 UTC

      The perl monks commentary you point to ("The Great Computer Language Shootout") was last updated 7 years ago.

      The tasks now shown on the benchmarks game weren't shown 7 years ago.

      The Perl :: Java comparison now shown on the benchmarks game website didn't exist 7 years ago.

        And then what?

Re: performance of perl vs java
by thundergnat (Deacon) on Oct 27, 2011 at 20:50 UTC

    In the vast majority of cases, barring painstaking optimization, you will probably find that selecting an appropriate algorithm will have a much larger effect on program run time than the language the program is written.

    Not particularly tuned; tested on a 6 year old computer:

    use warnings; use strict; use Time::HiRes qw/ tv_interval gettimeofday/; my $time0 = [gettimeofday]; use warnings; use strict; my $max = 100; my @primes = ( 2, 3 ); #seed the primes my $this = $primes[-1]; while ( $max > scalar @primes ) { $this += 2; my $sqrt = $this**.5; for (@primes) { if ( $_ > $sqrt ) { push @primes, $this; last; } next if $this % $_; last; } } my $elapsed = tv_interval( $time0, [gettimeofday] ); print "Printing the first $max numbers that are prime... \n"; print "$_ is prime.\n" for @primes; print "Took $elapsed seconds.";
    Printing the first 100 numbers that are prime...
    2 is prime.
    3 is prime.
    5 is prime.
    ...
    ...
    521 is prime.
    523 is prime.
    541 is prime.
    Took 0.00096 seconds.
    
Re: performance of perl vs java
by CountZero (Bishop) on Oct 27, 2011 at 20:55 UTC
    If one writes java code in Perl one should not be surprised of the bad performance.

    The following is a more perlish version:

    use Modern::Perl; use Time::HiRes qw/time/; my $start = time; my $top = 550; my $max = 100; my @primes; my $prime; for ( 2 .. $top ) { $prime = $_; next if $primes[$_]; last unless --$max; { local $_; $primes[ $_ * $prime ] = 1 for 2 .. $top / $prime; } } my $found = time; say $_ for ( grep { !$primes[$_] } 2 .. $prime ); my $end = time; say sprintf "Found all: %.6f seconds", ( $found - $start ); say sprintf "Printing all: %.6f seconds", ( $end - $found ); say sprintf "Running time: %.6f seconds", ( $end - $start );
    Output:
    2 3 5 7 11 13 17 19 23 29 31 ... 491 499 503 509 521 523 541 Found all: 0.000692 seconds Printing all: 0.000879 seconds Running time: 0.001571 seconds
    This application of the Sieve of Erasthotenes finds 100_000 primes in 3 seconds (and then takes 6 seconds to print them on the screen), so it is pretty fast.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Very nice!

      But say sprintf"...", and not printf"...\n"? Just curious.

        I like say, no other reason.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: performance of perl vs java
by repellent (Priest) on Oct 30, 2011 at 05:10 UTC
    Perl is a great language to learn, and I hope you'd remain around on PerlMonks to see the cool things you could do with it. It's usually fast enough, but more importantly, it's highly "optimized" for programmer effort such that you can get more done with minimal coding.

    Performance comparisons between two language implementations is hard to get right. You need to know the intricacies of both languages to avoid an apples vs oranges comparison.

    Here's a different Perl implementation that runs a lot faster on crappy hardware. Rehashing merlyn's article, I got the following code, which uses core Perl features only, to find all primes <= 3_000_000 (216816 total) in 9 secs:
    timethis for 1: 9 wallclock secs ( 7.64 usr + 1.22 sys = 8.86 CPU) +@ 0.11/s (n=1)

    This is run on FreeBSD vmware (256MB RAM) on an 8 year-old Athlon XP.


    Update: Added preamble for OP.

      awesome, well-thought, well-worded post

      What!? You're not a repellent at all, repellent!

      But this will find 3,000,000 over six times in a second:

      use strict; use warnings; use feature 'say'; use Benchmark qw/timethis/; use Inline 'C'; my $search_to = 3000000; timethis -10, \&eratos_inline_c; # Thin wrapper to bind input params for the benchmark. sub eratos_inline_c { return @{inline_c_pa_eratos_primes( $search_to )}; } __DATA__ __C__ /* Find all primes up to 'search_to' using the Sieve of Eratosthenes. +*/ AV * inline_c_pa_eratos_primes ( int search_to ) { AV* av = newAV(); int* primes = 0; int i; Newx( primes, search_to + 1 , int ); if( ! primes ) croak( "Failed to allocate memory.\n" ); for( i = 0; i <= search_to; i++ ) primes[i] = 1; for( i = 2; i * i <= search_to; i++ ) { if( primes[i] ) { int j; for( j = i; j * i <= search_to; j++ ) primes[ i * j ] = 0; } } for( i = 2; i <= search_to; i++ ) { if( primes[i] == 1 ) av_push( av, newSViv( i ) ); } Safefree( primes ); return sv_2mortal( av ); }

      Dave

        Thanks for the Inline C approach. That showcases one of Perl's strengths: to be able to dive down lower-level to C (via XS) and glue it back to Perl-land if we need the extra performance, all with minimal effort.

        I'm curious - how long does my Perl primes(3_000_000) take on your machine?

        Also, what are your machine specs?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://934178]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2014-09-17 02:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (56 votes), past polls