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});