この間からDateTime::TimeZoneをほげほげしてたんですが、結局のところDT::TZをいくらXS化して、インスタンス毎のに数個あるSVを小さくしたところでメモリフットプリントはほとんど変わらない、という現実にぶちあたりました。
前回このコードをいじってた時にも同じような事にぶちあたったので色々悩んだのですが、多分XSコードからPerlに構造体を渡す時にSVを作ってるからなんじゃないかと、はたとおもいあたったのです。
typedef struct hoge {
IV poop;
} hoge;IV
get_poop(self)
SV *self;
PREINIT:
hoge *myhoge;
CODE:
myhoge = get_hoge(self);
RETVAL = myhoge->poop;
OUTPUT:
RETVAL
ってした時に、もちろんIVはint32とかなのでSvIVよりは小さいんだけど、結局裏でRETVALはnewSViv(myhoge->poop)されてるからSV分のメモリをくっちまうわけなんだな。ただこのpoopをPerl側で使う部分が少なければ少ない程、一旦確保したメモリ領域を再利用できる可能性が高いので、効率はよくなる。そんなわけでアクセッサーを使う機会が多いとC structで対処する分のメモリ使用削減率というのは結局SVが作られてしまうのでガクンと落ちる訳だ。
同様に、newSV*()を呼ぶ回数が増えればそれだけCコードに変換した分の効率アップ分が削ぎ落とされる。
ということはXS化でもっとも恩恵を受けるにはアルゴリズム全体をCで書く事なんだろうな。DateTimeの場合は日付/時間計算を全部Cからできたら最高だと思われる。