素数を求める(4)
次は、2つの方式の速度比較。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 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