Update: I just benchmarked my original suggestion ('Lowest'), and it performs significanly worse than using sort; it's only faster with $num less than 3, and a $hash_size of several thousand :-(
#!/usr/bin/perl -w
require 5;
use strict;
use Benchmark;
use vars qw( $hash_size %random_hash $num );
$num = 2;
$hash_size = 1000;
# Generate random hash
my $r;
for ($r=1; $r<=$hash_size; $r++) {
$random_hash{"$r"} = int(rand(1000));
}
sub Lowest(\%) {
my $hashref = shift;
my %hash = %{$hashref};
my $position;
my $current;
my @lowest;
for ($position=0; $position<$num; $position++) {
my $min;
my $elem;
foreach $elem (keys %hash) {
if (!defined($min) || $hash{$elem} < $min) {
$min = $hash{$elem};
$current = $elem;
}
}
$lowest[$position] = $min;
delete $hash{$current};
last if !(%hash);
}
return @lowest;
}
sub Sort(\%) {
my $hashref = shift;
my %hash = %{$hashref};
my @lowest = (sort {$b <=> $a} values %hash)[0..--$num];
return @lowest;
}
timethese (
-20,
{
'Method 1' => 'Lowest(%random_hash)',
'Method 2' => 'Sort(%random_hash)'
});
exit;
abowley@lave:~$ ./lowest.pl
Benchmark: running Method 1, Method 2, each for at least 20 CPU second
+s...
Method 1: 25 wallclock secs (19.80 usr + 0.21 sys = 20.01 CPU) @ 42
+.53/s (n=851)
Method 2: 25 wallclock secs (20.33 usr + 0.22 sys = 20.55 CPU) @ 43
+.16/s (n=887)
|