Hacker News new | comments | show | ask | jobs | submit login

FWIW, in Perl 6, gradual type checking and function signatures do exist, and parameter flattening is only applied if the signature calls for it.

    sub foo(@array,$scalar) { }
    foo( 42, [1,2,3] );    # compile time error
Signatures are also first class citizens in Perl 6: check out https://docs.perl6.org/type/Signature for more information.



I was excited about Perl6 until I ran a prime number crunching benchmark which ran slower than everything else. I'll stick with Perl5 or move to Ruby. We too use Mojolicious and are very happy with it.


How long ago did you try that number crunching benchmark?


Recently, using Rakudo Star 2017.10. The algorithm adds numbers of the form i+j+2ij into a hash of non primes, then takes k not in that hash and pushes 2k+1 into an array of primes. These are basic operations, but Perl6 simply takes minutes to find primes up to 10k. Even Tcl, which lags behind anything else but Perl6 does it an order of magnitude faster. If you increase to 100k then you could probably go have a pizza in town and it would still be crunching after you were back. So it's definitely not the JIT compliation stage that makes it so slow.


As the author of this recent post https://perl6advent.wordpress.com/2017/12/16/ I'd be really interested in seeing your code for primes. You might enjoy seeing the output of `perl6 --profile` to see if there is any glaringly obvious place its being slow. You get a nice interactive html report.

I find it kind of funny primes are constantly used as a first filter on using Perl 6, despite it being one of the only languages with an efficient built in .is-prime method on integer types >;P I have a more contemporary version of Rakudo built locally too, so can see if this is something that's already gone away if you dont mind throwing your code in a gist/pastebin somewhere?


perl5 0m0.156s https://p.thorsen.pm/2d70bb2da612

perl6 0m6.615s https://p.thorsen.pm/ab1769fe2778

This is Rakudo version 2017.10 built on MoarVM version 2017.10 implementing Perl 6.c. It's built with radkudobrew. Results are consistent across several platforms, I've also built on an iMac with OS X 10.1. This one is built on Ubuntu 16.04 x86-64.


I'm not exactly sure I understand the algorithm, but if it is only supposed to generate prime numbers upto 1000, than it appears to erroneously include `999` as a prime number.

FWIW, if I would just be interested in the prime numbers upto 1000, I would write that like this:

    (1..1000).grep( *.is-prime )
Which for me executes within noise of your Perl 5 algorithm. For larger values on multi-CPU machines, I would write this as:

    (1..2500).hyper.grep( *.is-prime )
Around 2500 it becomes faster to `hyper` it, so the work gets automatically distributed over multiple CPU's.

Am currently researching as to why your Perl 6 algorithm is so slow.


The algorithm is an implementation of the Sieve of Sundaram. 999 might have slipped in by an off by one error. Thanx for the suggestion of using is-prime, but in order to benchmark multiple languages, I need to run the same thing everywhere.


Turns out that even though primes are integers, in your Perl 6 version, every calculation was done by using floating point. And this was caused by the call to the subroutine. If you would do:

    sieve_sundaram(1000)
instead of:

    sieve_sundaram(1e3)
then it all of a sudden becomes 4x as fast. In Perl 5 you never know what you're dealing with with regards to values. In Perl 6 if you tell it to use a floating point, it will infect all calculations to be in floating point afterwards. `1e3` is a floating point value. `1000` is an integer in Perl 6.

Also, you seem to have a sub-optimal algorithm: the second `foreach` doesn't need to go from `1..$n`, but can go from `$i..$n` instead. This brings down the runtime of the Perl 5 version of the code to 89 msecs for me.

Since your program is not using BigInt in the Perl 5 version, it is basically using native integers. In Perl 6, all integer calculations are always BigInts, unless you mark them as native. If I adjust your Perl 6 version for this, the runtime goes down from 4671 msecs to 414 msecs for this version:

    sub sieve_sundaram(int $n) {
        my %a;
        my int @s = 2;
        my int $m = $n div 2 - 1;
        for 1..$n -> int $i {
            for $i..$n -> int $j {
                my int $p = $i + $j + 2 * $i * $j;
                if $p < $m {
                    %a{$p} = True;
                }
            }
        }
        for 1..$m -> int $k {
            if ! %a{$k} {
                my int $q = 2 * $k + 1;
                @s.push($q);
            }
        }

        return @s;
    }

    sieve_sundaram(1000);
So, about 11x faster than before. And just under 5x as slow as the Perl 5 version.

I could further make this idiomatic Perl 6, but the most idiomatic version I've already mentioned: `(1..1000).grep( *.is-prime)`


Can we please continue this discussion out of this thread, on a proper Perl forum? I haven't found any contact pointers for you or Ultimatt.


https://stackoverflow.com/questions/tagged/perl6 perhaps?

Or on IRC: #perl6 on irc.freenode.org ?

Or the perl6-users mailing list?





Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: