あいつの日誌β

働きながら旅しています。

配列の件数を取得する方法を考える

お詫び

この記事は最終的にあやふやな結論になっています。ごめんなさい。

本文

最近自分のコードを見つめ直すためにやたらとベンチとっています。

#!/usr/bin/env perl
use strict;
use warnings;

use Benchmark qw/cmpthese timethese/;

my $count = 10_000_000;

my @array = (qw/hoge fuga piyo foo bar moga muge mogo/);

cmpthese timethese $count, {
    count1 => sub {
        my $count = scalar @array;
        $count == 8 or die;
    },
    count2 => sub {
        my $count = @array;
        $count == 8 or die;
    },
    index1 => sub {        
        my $index = $#array;
        $index == 7 or die;
    },
    index2 => sub {
        my $index = scalar @array - 1;
        $index == 7 or die;
    },
};

実行結果

:!perl bench/array_count.pl
Benchmark: timing 10000000 iterations of count1, count2, index, index2...
    count1:  1 wallclock secs ( 1.14 usr +  0.00 sys =  1.14 CPU) @ 8771929.82/s (n=10000000)
    count2:  1 wallclock secs ( 1.17 usr +  0.00 sys =  1.17 CPU) @ 8547008.55/s (n=10000000)
     index:  3 wallclock secs ( 1.50 usr +  0.00 sys =  1.50 CPU) @ 6666666.67/s (n=10000000)
    index2:  3 wallclock secs ( 1.46 usr +  0.01 sys =  1.47 CPU) @ 6802721.09/s (n=10000000)
            Rate  index index2 count2 count1
index  6666667/s     --    -2%   -22%   -24%
index2 6802721/s     2%     --   -20%   -22%
count2 8547009/s    28%    26%     --    -3%
count1 8771930/s    32%    29%     3%     --

私はcount1のようにscalarを明示するのが好きなのでうれしい結果です。本来的には余計な記述のはずなので推奨されないと思っていましたが。

$#array は @array -1より高速なので純粋にindexを求める場合はこう書いたほうがいいなあ。時々次のように記述しているときがある

for my $index ( 0 .. scalar @array - 1 ) {
...
}

こう書こう

for my $index ( 0 .. $#array ) {
...
}

2011-12-14 午前0時頃追記

ってあれ?index1とindex2の計測結果を見間違えてる気がする。明日要確認。

たびたび追記

念の為再計測

1回目

index2 5434783/s     --   -14%   -18%   -28%
index1 6329114/s    16%     --    -5%   -16%
count1 6666667/s    23%     5%     --   -11%
count2 7518797/s    38%    19%    13%     --

2回目

            Rate index1 count1 index2 count2
index1 4739336/s     --   -13%   -15%   -28%
count1 5464481/s    15%     --    -2%   -17%
index2 5586592/s    18%     2%     --   -15%
count2 6578947/s    39%    20%    18%     --

3回目

            Rate index2 count2 index1 count1
index2 5464481/s     --    -8%   -13%   -17%
count2 5952381/s     9%     --    -5%   -10%
index1 6250000/s    14%     5%     --    -5%
count1 6578947/s    20%    11%     5%     --

時々速度が入れ替わるので勘違いかも。どっちの書き方も変わらないって事でいいかな。