List::Util, List::MoreUtils

Perl Best PracticeにList::Utilモジュールを使ったほうがいいよん、と書かれていたので試してみる。

ベンチマーク

効率よく実装されているとのことなので、ベンチマークしてみる。
とりあえず最大値。

use Benchmark qw(:all);
use List::Util qw(max reduce);

my @list = qw(1 2 3 4 5 6 7 8 9 10);

sub max_by_util {
    return max @list;
}

sub max_by_self {
    my $max;
    for my $val (@list) {
        $max = ($max > $val) ? $max : $val;
    }
    return $max;
}

timethese(1_000_000, {
  'max_by_util' => 'max_by_util()',
  'max_by_self' => 'max_by_self()',
});
Benchmark: timing 1000000 iterations of max_by_self, max_by_util...
max_by_self:  6 wallclock secs ( 6.10 usr +  0.01 sys =  6.11 CPU) @ 163666.12/s (n=1000000)
max_by_util:  1 wallclock secs ( 1.04 usr +  0.00 sys =  1.04 CPU) @ 961538.46/s (n=1000000)

5倍くらい速い!そして、自分でmax書くのは面倒なので使ったほうがよいですね。

reduce/uniq

配列参照のリストからユニークな要素を取り出す。Perl Best Practiceに書かれていたそのまま。

use List::Util qw(max reduce);
use List::MoreUtils qw(uniq);

my @list_sets = (
    [qw(1 3 5)],
    [qw(8 4 1)],
    [qw(0 6 7)],
    [qw(9 7 2)],
);

my $uniq_list_ref = reduce { [uniq @$a, @$b] } @list_sets;
printf("%s\n", join(q{,}, @$uniq_list_ref));
#1,3,5,8,4,0,6,7,9,2