List::UtilsBy::XSが書けました。

List::UtilsBy::XSを書いてます。 - Life is very short


の作業がとりあえずひと通り終わりました。
List::UtilsByのテストユーティリティがなぜか無限ループして
しまうことや、Lightweight Callback APIの制限があったり
しますが、List::UtilsByから持ってきたテストは概ね通っています。

ベンチマーク

Perl 5.14.1の結果は以下のようになりました。

Benchmarking List::Util and List::UtilsBy::XS
Bench: sort_by
      Rate   pp   xs
pp  7729/s   -- -37%
xs 12217/s  58%   --

Bench: nsort_by
      Rate   pp   xs
pp  9050/s   -- -71%
xs 31716/s 250%   --

Bench: rev_sort_by
      Rate   pp   xs
pp  7450/s   -- -38%
xs 11933/s  60%   --

Bench: rev_nsort_by
      Rate   pp   xs
pp  8426/s   -- -74%
xs 32582/s 287%   --

Bench: max_by
      Rate   pp   xs
pp 28768/s   -- -26%
xs 38711/s  35%   --

Bench: min_by
      Rate   pp   xs
pp 25373/s   -- -33%
xs 38059/s  50%   --

Bench: uniq_by
      Rate   pp   xs
pp 12426/s   -- -56%
xs 28109/s 126%   --

Bench: partition_by
      Rate   pp   xs
pp 11598/s   -- -30%
xs 16593/s  43%   --

Bench: count_by
      Rate   pp   xs
pp 17148/s   -- -34%
xs 26065/s  52%   --

Bench: zip_by
      Rate   pp   xs
pp 10288/s   -- -45%
xs 18797/s  83%   --

Bench: zip_by
       Rate   pp   xs
pp 160777/s   -- -43%
xs 283880/s  77%   --

Bench: weighted_shuffle_by
     Rate   pp   xs
pp 1532/s   -- -76%
xs 6279/s 310%   --

Bench: bundle_by
      Rate   pp   xs
pp 34796/s   -- -26%
xs 47287/s  36%   --

だいたい早くなっています。Lightweight Callback API
使っていないものも思った以上に差が出ました。


用いたスクリプトは以下のものです。
こちらになります。

制約

  1. コールバック関数内で $_を変更できないインタフェースがある
  2. コールバック関数内で @_でアクセスできないインタフェースがある
  3. extract_byで weak-referenceの情報を保持できない

初めの 2つは Lightweight Callback APIによるところだと思います。
(ドキュメントにはその APIが提供されないと書いている。
実装可能かもしれないけど、参考にできるものがない。)
最後の私の知識不足によるところだと思います。いくつか試して
みましたが、panicにしかなりませんでした。

Lightweight callback APIを使うに当たっての注意

Perl5.14.1で作業をしていたのですが、Perl5.8でも一応と思って
試したところ、リンクがちゃんとできないというエラーに会いました。
どこみても解決方法が書いていないということで、ソースコード
grepをかけてみたら解決方法がわかりました。


Lightweight callback APIを使う場合は, コンパイル時のフラグに
"-DPERL_EXT"を付ける必要がありました。Changelogに書いてました。
List::Utilの為だけに追加されたもののようです。

おわりに

List::UtilsBy::XSを実装したことについて紹介しました。
今回の件を通じて XSの基礎を学ぶことができました。
次はライブラリのバインディングにチャレンジしようと思います。


現時点での実装だと元のものと差し替えて使うということが
完璧にできないので CPANにはアップしないつもりです。

追記

メモリリークバグを修正しました。
Thanks @