itochin2の日記(仮)

主に備忘録。Perl、MySQL、Unity、開発管理などについて情報を残していきたい。

List::MoreUtilsモジュールは便利

hashの配列とかから、ある要素が全てhogeかどうかを調べるロジック。

List::MoreUtils::allを使うと便利だった。
http://search.cpan.org/~vparseval/List-MoreUtils-0.22/lib/List/MoreUtils.pm

ベンチマークを取ったところ、foreachで頑張るより約25%早いしソースコードもシンプル。
自分で開発するより、すでにあるものを使った方がいいって
Perlベスト・プラクティスも言ってたし、こっちの方が良さそうだ。

#!/usr/bin/sh perl

use strict;
use warnings;
use List::Util qw(first);
use List::MoreUtils qw(all);
use Benchmark qw(:all);

my @enable_list = (+{ status => 1, }) x 100;

# 配列内のstatusが全て1かどうかを判定するロジック
cmpthese(
    500000,
    +{
        'foreach' => sub {
            # ステータスがNGなのを見つけるまでループ回す作戦
            my $all_enable = 1;
            foreach my $data (@enable_list) {
                if ($data->{status} == 0) {
                    $all_enable = 0;
                    last;
                }
            }
        },
        'grep' => sub {
            # ステータスがOKの個数をgrepで探して元の個数と比較する作戦
            my $all_enable = 0;
            my $enable_cnt = grep {
                $_->{status} == 1
            } @enable_list;
            $all_enable = (scalar(@enable_list) == $enable_cnt) ? 1 : 0;
        },
        'first' => sub {
            # ステータスがNGなのをfirstで探す作戦
            my $all_enable = 0;
            my $disable_data = first {
                $_->{status} == 0 
            } @enable_list;
            $all_enable = ($disable_data) ? 0 : 1;
        },
        'List::MoreUtils::all' => sub {
            # List::MoreUtils::allを使う作戦
            my $all_enable = all { $_->{status} == 1 } @enable_list;
        },
    }
);

=pod
$ perl list_util.all.pl
                   Rate       foreach          grep        first   List::Util::all
foreach         120192/s           --           -3%         -17%              -20%
grep            124378/s           3%            --         -14%              -18%
first           145349/s          21%           17%           --               -4%
List::Util::all 151057/s          26%           21%           4%                --
=cut