素数を求める(3)
という訳で、最初の実装を高速化してみた。
use strict; use warnings; use v5.10; use Benchmark qw/cmpthese/; die 'Usage: perl aaa.pl <integer>' if scalar(@ARGV) == 0; my $max_num = $ARGV[0]; cmpthese( 10, { 'before' => sub { my @prime = calc_prime1( $max_num ); }, 'after' => sub { my @prime = calc_prime2( $max_num ); } } ); sub calc_prime1 { my $n = shift; my @ret = (); if ( $n < 2 ) { return @ret; } my @wk = 2..$n; while ( @wk ) { my $prime = shift @wk; @wk = grep { ($_ % $prime); } @wk; push @ret, $prime; } return @ret; } sub calc_prime2 { my $n = shift; my @ret = (); if ( $n < 2 ) { return @ret; } my @wk = 0..$n; $wk[0] = -1; $wk[1] = -1; for (my $i=0; $i<=$n; $i++) { next if $wk[$i] < 0; my $prime = $wk[$i]; for (my $j=$i+1; $j<=$n; $j++) { next if $wk[$j] < 0; if ( ($wk[$j] % $prime) == 0 ) { $wk[$j] = -1; } } } return grep { $_ != -1; } @wk; }
実行結果はこんな感じ。
$ perl aaa.pl 10000 s/iter after before after 1.82 -- -88% before 0.218 733% --
うーん、grep
しまくりが良くなかったのかなー。
もしくは、push
とか、shift
とか。
ここは憶測で語っても仕方ないので、こんな感じで。
という訳で、これで余りを計算しない方式と比較する準備ができました。
続く。
Leave a Comment