Q:

Perl6 vs Perl5 benchmarking using prime numbers

This is a discussion moved from this HN thread here, regarding benchmarking Perl6 vs. Perl5 vs. other languages using an algorithm which implements the Sieve of Sundaram for finding prime numbers.
Here's original code in the original thread:
perl5 0m0.156s 
perl6 0m6.615s
The problem is that the Perl6 version takes too long to find primes, compared to the Perl5 implementation. Part of it is due to using float as input, but still, it's too slow.
The objective is not necessarily to optimize the algorithm, but rather to identify why Perl6 is so slow compared to other languages.

A:

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.
The most idiomatic version for getting primes in Perl 6 is:
(1..1000).grep( *.is-prime )

Which for me executes within noise of your original 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.

A:

I don't think I can add much more to what Liz said. Other than: 

"but in order to benchmark multiple languages, I need to run the same
  thing everywhere"

...where "same" is defined as similar looking syntax in English, is a very poor criteria for equivalence between radically different programming languages. Perl 6 has very similar or even identical syntax to Perl 5 whilst performing very different semantics underneath. The whole language has been tuned for correctness with default easily reached syntax, rather than optimal behaviour. Another great example is Perl 6 strings, they are quite slow, they are always fully normalised unicode rather than a string of plain bytes. All operations on them consider unicode concepts of graphemes rather than bytes and byte offsets. Which is great! But the more equivalent type to a C/Perl 5 string is probably a Buf which sadly doesn't have anywhere near as many string like operators/methods but is just a block of bytes.

