素数を列挙する4

「mod 6で1か5」を探索する方法でいってみます.

use Benchmark;

$x=primefactory2();
$count=5000;

timethese($count, {'p1' => '$x->();', 
                  }
         );

sub next_cand{
    $_[0] + 2 * ($_[0] % 6 ==5) + 4*($_[0] % 6 ==1);
}


sub primefactory2{
    my @primes=(2,3,5);
    my $state=-1;
    return sub{
        $state++;
        return $primes[$state] if $state==0 or $state==1 or $state==2;
        my $prime_cand=next_cand($primes[-1]);
        my $th;
        SIEVE:
         $th = int(sqrt($prime_cand))+1;
        foreach my $d ( @primes ){
            last if $d>$th;
            if ( ($prime_cand % $d ==0)  ){
                $prime_cand = next_cand($prime_cand);
                goto SIEVE; 
            }
        }
        @primes=(@primes,$prime_cand);
        return $primes[-1];
    }
}

ループ回数268271は小さくなり,時間は,

Benchmark: timing 5000 iterations of p1...
        p1:  4 wallclock secs ( 3.86 usr +  0.00 sys =  3.86 CPU) @ 1295.34/s (n=5000)

となりました.微妙な差ですが,これが一番速そうです.もっともHaskellのときのような圧倒的な差はありません.