my $N = 20; my $collect = 5 * $N; my $threshold; while (<>) { my ($id, $score) = split ' '; push @top, [$id, $score] if !defined $threshold or $score >= $threshold; if(@top > $collect) { @top = sort { $b->[1] <=> $a->[1] } @top; splice @top, $N; $threshold = $top[-1][1]; } } if(@top > $N) { @top = sort { $b->[1] <=> $a->[1] } @top; splice @top, $N; }