2012/11/24

Sub::Sequence と splice と natatime の benchmark

きのう出した Sub::Sequence ですが、速度も気になるところだったので、splice と natatime とあわせてベンチマークとってみました。ソースはあとに回してまず結果をみると、以下のような感じになってました。

           Rate natatime      seq   splice
natatime 2.50/s       --     -13%     -25%
seq      2.87/s      15%       --     -14%
splice   3.33/s      33%      16%       --

splice 速いですね。さすが組み込みです(破壊的なのが許容できれば最強選択肢)。List::MoreUtils#natatime も速いんじゃないかと思いましたが、そんなでもなかったです。取り急ぎ自分の想定しているユースケースになるようなパラメータ配分をした結果が上ですが、実は、一度に処理する要素数($at_time) を小さくすると、natatimeseq を逆転してたりしました。

とはいえ、まあ、記述の簡易さでは seq が良さそうに思えませんか? ねぇ ねぇ ねぇ ねぇ

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

use Benchmark qw/timethese cmpthese/;

use Sub::Sequence;
use List::MoreUtils qw/natatime/;

my $list_items = 1000_000;
my @ID_LIST = (1..$list_items); @ID_LIST = ();
my $at_time    = 100;
my $result = timethese (5, {
    'seq'      => '&logic1;',
    'splice'   => '&logic2;',
    'natatime' => '&logic3;',
});

cmpthese $result;

sub logic1 {
    @ID_LIST = (1..$list_items);
    my $result = seq \@ID_LIST, $at_time, sub {
        1;
    };
}

sub logic2 {
    @ID_LIST = (1..$list_items);
    my $result;
    while ( my @list = splice(@ID_LIST, 0, $at_time) ) {
        push @{$result}, 1;
    }
}

sub logic3 {
    @ID_LIST = (1..$list_items);
    my $result;
    my $it = natatime $at_time, @ID_LIST;
    while ( my @list = $it->() ) {
        push @{$result}, 1;
    }
}

サイト内検索