素数を求める(4)
次は、2つの方式の速度比較。
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, { 'calc1' => sub { my @prime = calc_prime1( $max_num ); }, 'calc2' => sub { my @prime = calc_prime2( $max_num ); } } ); sub calc_prime1 { 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; } 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; for (my $j=($i+$i); $j<=$n; $j+=$i) { $wk[$j] = -1; } } return grep { $_ != -1; } @wk; }
実行結果はこんな感じ。
$ perl aaa.pl 10000 (warning: too few iterations for a reliable count) s/iter calc1 calc2 calc1 1.89 -- -99% calc2 1.00e-02 18760% --
分かってはいたんですけどね、体感で違い過ぎたので。
ただ、添え字でどうこうするのは、
大きな素数を計算するのには向かない気がするので、
その場合は時間が掛かってでも、
すでに見つかった素数で余りを計算する方が現実的な気がします。
でも、そこはSSDを使えば、もっと早く計算できたりするんですかね。
という訳で、素数の計算はここまで。
おしまい。
Leave a Comment