XSを書く難しさ
最近思うが,つくづくXSは難しい。いとも簡単にSEGVを起こし,デバッグが難しく,それゆえモジュール作者のやる気が失われたときのリスクが非常に大きい。そうやって多大なリスクを犯してXSを書いても,肝心の速度がPurePerl以上に遅いことも少なくない。
最近だとClass::MOPにパッチを送ったのだけど,その後幾度かのバグフィクスや修正を経た0.72現在,パフォーマンスがかなり落ちている。
最初のパッチでのパフォーマンス(いずれもPerl 5.8.9 linux multi-thread with -DDEBUGGING):
Initialization: Rate pp xs pp 2327/s -- -18% xs 2844/s 22% -- Looking into the stash: Rate pp xs pp 20958/s -- -72% xs 73770/s 252% -- Getting the cache: Rate pp xs pp 185579/s -- -80% xs 918728/s 395% --
Class::MOP バージョン0.72:
Initialization: Rate pp xs pp 2349/s -- -1% xs 2378/s 1% -- Looking into the stash: Rate pp xs pp 20479/s -- -50% xs 40959/s 100% -- Getting the cache: Rate pp xs pp 172463/s -- -76% xs 714566/s 314% --
理由としては,現在のバージョンではPERL_NO_GET_CONTEXTを定義していないこと*1,シンボルテーブル(スタッシュ)を直接操作する代わりに内部でget_all_package_symbols()を呼んでいること*2などがあげられる。
彼らのようなエキスパートでさえ,このように「リファクタリング」によってパフォーマンスを落としてしまうほど,XSを書くのは難しい。
たまたま自分が関わったことなのでClass::MOPを扱ったが,別にClass::MOPの開発陣を批判したいのではない。たとえば,最初にClass::MOPへ送ったパッチにもバグが一つあったし*3,それ以外の自分が書いたXSにもまだバグはあるだろう。BやPadWalkerのバグのせいでData::Dump::Streamerが落ちるのは日常茶飯事である。XSを書くのは本当に難しい。
とはいえ,その苦労に値する効果があるからXSはやめられない!