PERL_NO_GET_CONTEXT
XSモジュールを書くときはPERL_NO_GET_CONTEXTを試してみるといいようだ。
perlgutsによれば,perlのビルド時にPERL_IMPLICIT_CONTEXTが指定されているとき,PERL_NO_GET_CONTEXTマクロをperlヘッダの#includeの前に定義すると効率がよくなる,とある。この動作がデフォルトでないのはithread実装以前のPerlとの互換性のためとあるので,最近のXSモジュールならば常にPERL_NO_GET_CONTEXTを定義してもよさそうである*1。
そしてPERL_NO_GET_CONTEXTにより,PerlAPIへのアクセスが劇的に速くなる。たとえば,Acme::StringFormatで試してみると,PERL_NO_GET_CONTEXTを定義するだけで5倍ほど高速になった。
$ perl example/benchmark.pl number of arguments: 1 Benchmark: running %, sprintf for at least 1 CPU seconds... %: 1 wallclock secs ( 1.05 usr + 0.00 sys = 1.05 CPU) @ 136533.33/s (n=143360) sprintf: 1 wallclock secs ( 1.08 usr + 0.00 sys = 1.08 CPU) @ 799971.35/s (n=865569) Rate % sprintf % 136533/s -- -83% sprintf 799971/s 486% --
$ perl -Mblib example/benchmark.pl number of arguments: 1 Benchmark: running %, sprintf for at least 1 CPU seconds... %: 0 wallclock secs ( 1.06 usr + 0.00 sys = 1.06 CPU) @ 616518.34/s (n=655359) sprintf: 2 wallclock secs ( 1.07 usr + 0.00 sys = 1.07 CPU) @ 803136.32/s (n=860159) Rate % sprintf % 616518/s -- -23% sprintf 803136/s 30% --
もっともこれは極端な例で,通常はここまで劇的に改善することはないようだが。
See Also perlguts / How multiple interpreters and concurrency are supported.