Perl/XSが得意なこと

最近ひたすらXSを書いていて思ったのが,XSはやっぱり速いということ。

ただ,いつでも無条件に速いというわけでもなく,何も考えずに書くとPurePerlのコードより遅くなることも珍しくない。実際,最近書いたShikaやMOPのXS版もいきなり高速だったわけではなく,一番最初のコードはPurePerlのほうが10%-30%ほど高速だった。

いろいろベンチマークをとった結果の感触として,XSの得手・不得手が分かってきたのでメモしておく。ちなみに下記で「注意を払う」というのは内部で呼ばれるmalloc()を極力減らすという意味で使っている。SVの生成自体はmalloc()を伴わないことが多い*1が,文字列の生成/連結や配列の生成/push/unshiftでは内部でmalloc()が呼ばれる可能性が高く,速度を落とす原因となる。

得手分野

  • ループ - XSのループが早いというより,Perlのループが非常に遅い
  • 条件分岐 - 条件が複雑になるとかなり速い
  • グロブ操作 - 注意深く扱えばかなり速い
  • 配列操作 - 特にTieされてないことが確信できる場合,非常に速い
  • ハッシュ操作 - そこそこ速い
  • クロージャ生成 - 扱いが非常に難しいがかなり速い

不得手分野

  • サブルーチン呼び出し - 細心の注意を払ってもPurePerlとほぼ同じ
  • メソッド呼び出し - call_method()がPurePerlよりかなり遅く,細心の注意を払ってcall_sv(x, flag | G_METHOD)をしてもPurePerl版より少し遅いかほぼ変わらない