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)