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を書いているということを紹介しました。