List::UtilsBy::XSを書いてます。

XSの勉強ということで, List::Utilや List::MoreUtilsに
似ている List::UtilsByの XS版を書いています。

ベンチマーク

まだすべてが実装できているわけではないんですが、
sort_by, nsort_by, max_byについて見てみました。

ベンチマーク用のコード
#!perl
use strict;
use warnings;

use List::UtilsBy;
use List::UtilsBy::XS;

use String::Random;
use Benchmark qw(cmpthese);

my $generator = String::Random->new;

my @array;
for my $i (1..1000) {
    push @array, {
        number => int(rand(100)),
        name   => $generator->randregex('[A-Za-z0-9]{8}'),
    };
}

cmpthese(-1, {
    sort_by_pp => sub { List::UtilsBy::sort_by { $_->{name} } @array; },
    sort_by_xs => sub { List::UtilsBy::XS::sort_by { $_->{name} } @array; },
});

cmpthese(-1, {
    nsort_by_pp => sub { List::UtilsBy::nsort_by { $_->{number} } @array; },
    nsort_by_xs => sub { List::UtilsBy::XS::nsort_by { $_->{number} } @array; },
});

cmpthese(-1, {
    max_by_pp => sub { List::UtilsBy::max_by { $_->{number} } @array; },
    max_by_xs => sub { List::UtilsBy::XS::max_by { $_->{number} } @array; },
});
結果
             Rate sort_by_pp sort_by_xs
sort_by_pp  634/s         --       -39%
sort_by_xs 1037/s        64%         --

              Rate nsort_by_pp nsort_by_xs
nsort_by_pp  760/s          --        -74%
nsort_by_xs 2955/s        289%          --

            Rate max_by_pp max_by_xs
max_by_pp 3170/s        --       -4%
max_by_xs 3319/s        5%        --

max_by以外それなりに早くなっているという感じです。
max_byが他とそんなに実装が異なるわけではないので、
なにか問題があるのかもしれません。

実装出来ていない機能

元の List::UtilsByのテストにサブルーチンリファレンスの中で
$_を undefしたり、$_[0]を参照したりというのがあったのですが、
それができていない。

理解出来ていないところ

mortal(揮発性)に関すること全般。


mortalをつけておくと無難という記述がちらほら見られたので,
とりあえず mortalってやるとうまく動いてくれないところが
ありました。Test::Valgrindの結果エラーが報告されないので、
メモリリークはないのかもしれないですが、このあたりは
闇雲に対応したと言わざるをえない。


なんで理解した上で問題がないか、効率はどうかってことを
検討していきたいと思います。

おわりに

List::UtilsBy::XSを書いているということを紹介しました。