use strict;
use warnings;
use Benchmark qw(timethese);
my $nb_elements = 2e6;
my @top3;
my @startArray;
push @startArray, ["", "", int rand (1e7)] for 1..$nb_elements;
sub discard_sort{
my @masterArray = @startArray;
my @top3 = sort {$b->[2] <=> $a->[2]} @masterArray[0..2];
my $min_top = $top3[2][2];
$nb_elements--;
for my $sub_aref (@masterArray [3..$nb_elements]) {
next if $sub_aref->[2] <= $min_top;
@top3 = (sort {$b->[2] <=> $a->[2]} $sub_aref, @top3)[0..2];
$min_top = $top3[2][2];
}
}
sub discard_manual{
my @masterArray = @startArray;
@top3 = sort {$b->[2] <=> $a->[2]} @masterArray[0..2];
my $min_top = $top3[2][2];
$nb_elements--;
for my $sub_aref (@masterArray [3..$nb_elements]) {
next if $sub_aref->[2] <= $min_top;
if ($sub_aref->[2] > $top3[0][2]) {
unshift @top3, $sub_aref;
pop @top3;
}
elsif ( $sub_aref->[2] > $top3[1][2]) {
$top3[2] = $top3[1];
$top3[1] = $sub_aref;
} else {
pop @top3;
push @top3, $sub_aref;
}
$min_top = $top3[2][2];
}
}
sub sort_strategy {
my @masterArray = @startArray;
my @top3 = (sort {$b->[2] <=> $a->[2]} @masterArray)[0..2];
}
timethese (5, {
'walk once with sort' => \&discard_sort,
'walk once manual insert' => \&discard_manual,
'sort' => \&sort_strategy});
####
Benchmark: timing 5 iterations of sort, walk once manual insert, walk once with sort...
sort: 60 wallclock secs (60.37 usr + 0.02 sys = 60.39 CPU) @ 0.08/s (n=5)
walk once manual insert: 3 wallclock secs ( 2.79 usr + 0.00 sys = 2.79 CPU) @ 1.79/s (n=5)
walk once with sort: 3 wallclock secs ( 2.76 usr + 0.00 sys = 2.76 CPU) @ 1.81/s (n=5)
####
Benchmark: timing 5 iterations of sort, walk once manual insert, walk once with sort...
sort: 170 wallclock secs (169.96 usr + 0.03 sys = 169.99 CPU) @ 0.03/s (n=5)
walk once manual insert: 7 wallclock secs ( 6.90 usr + 0.03 sys = 6.93 CPU) @ 0.72/s (n=5)
walk once with sort: 7 wallclock secs ( 6.86 usr + 0.00 sys = 6.86 CPU) @ 0.73/s (n=5)