挿入ソートとデータ列の関係(中編)
では、さっそくソートに掛かる時間を計測したいと思います。
use strict;
use warnings;
use v5.10;
use Benchmark qw/cmpthese timethese/;
use Array::Shuffle qw/shuffle_array/;
{
my $n = 10;
my @data = 1..2000;
my @data_asc_ary = map {
my @tmp = @data;
\@tmp;
} 1..$n;
my @data_rand_ary = map {
my @tmp = @data;
shuffle_array( @tmp );
\@tmp;
} 1..$n;
cmpthese( $n, {
'asc' => sub {
my $ary_ref = shift @data_asc_ary;
insert_sort( @{$ary_ref} );
},
'random' => sub {
my $ary_ref = shift @data_rand_ary;
insert_sort( @{$ary_ref} );
}
});
}
print "\n";
{
my @data_asc = 1..5000;
my @data_desc = reverse @data_asc;
timethese( 1, {
'asc ' => sub {
my @wk = @data_asc;
insert_sort( @wk );
},
'desc' => sub {
my @wk = @data_desc;
insert_sort( @wk );
}
});
}
sub insert_sort {
my @data = @_;
my $cnt = scalar( @data );
for (my $i=1; $i<$cnt; $i++) {
my $wk = $data[$i];
my $j = $i;
for (; 0<$j; $j--) {
if ( $wk <= $data[$j-1] ) {
last;
}
else {
$data[$j] = $data[$j-1];
}
}
$data[$j] = $wk;
}
return @data;
}
結果はこんな感じ。
$ perl aaa.pl
s/iter asc random
asc 1.38 -- -49%
random 0.696 98% --
Benchmark: timing 1 iterations of asc , desc...
asc : 9 wallclock secs ( 8.66 usr + 0.04 sys = 8.70 CPU) @ 0.11/s (n=1)
(warning: too few iterations for a reliable count)
desc: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(warning: too few iterations for a reliable count)
ランダムデータの場合と、小さい順に並んだデータだと、
だいたい倍くらいの差がつくようです。
そして、大きい順に並んだデータはソート済みのデータと等価なので、
ソートに掛かる時間が短過ぎて、他と比較のしようがないです。
あと、見直してて思ったのは、
シャッフルが無視できるようなデータ数でやれば、
もっとテストコードがシンプルかなーって思いました。
ここまではカンペ通りです。
続く。
Leave a Comment