Sorting 1000 items involves a _lot_ more than 1000 comparisons - which is really all you need. If you insist on your approach you should memoize vercmp() or use the orcish maneuver in your sort() callback. (Memoizing will accelerate it across all of your script, but the orcish maneuvre will accelerate your callback more because it avoids unnecessary function calls. Using both at once is not likely to be any worthwhile optimization over simply memoizing due to double bookkeeping though.)
But why build a list with all available versions and sorting it, when you can discard less recent new packages right as you build it? You're also wasting effort in other places. > # pkgname, ver, rel > my @installed = map { [ /^(.*)-([^-]+)-([^-]+)$/ ] } `rpm -qa`; > my %installed = map { $_->[0], $_ } @installed; my %installed = map { /^(.*)-([^-]+)-([^-]+)$/ ? ($1, [$2,$3]) : ()} `rpm -qa`; > my @available = map { [ /^((.*)-([^-]+)-([^-]+)\.[^.]+\.rpm)$/ ] } >/<a\s+href="([^"]+\.rpm)"/gi; my %available; for(/<a\s+href="([^"]+\.rpm)"/gi) { next unless /^((.*)-([^-]+)-([^-]+)\.[^.]+\.rpm)$/ and exists $installed{$1} and -1 == vercmp($2,$3, @{$installed{$_}}); $available{$1} = [$0, $2, $3] if not exists $available{$1} or -1 == vercmp($2,$3, @{$available{$1}}[1,2]); } # now printing results is trivial print map "$url/".$available{$_}[0]."\n", sort keys %available; -- Regards, Aristotle