2007年06月11日

3月くらいにkazeburoさんがメモしてた遅くなる話。

極端に遅くなる処理のベンチ例みたいなのがほしいかな
何やったら遅くなるかわかりました。
すごく正確に検証してるわけでも無いのですが、use overloadしたパッケージをblessするとき。
例えばURIやDateTime等のnew時。
この時にかかるCPUコストが激しく高いため、全体的にアプリケーションがもっさりと動く事になってました。

しかもFC4系列のディストリビューション全体で注意した方が良いかもです。
家はCentOS 4.4の perl 5.8.8-4.el4e1 のRPMで該当のパッチが混入していました。
書いたアプリが見込みよりもパフォーマンスが悪くて、最後の最後にまさかと思ってoverloadしてるモジュールを疑っていたらkazeburoさんにナイス指摘をしていただいて気づきました。
CentOSだから大丈夫だろうと油断してましたorz

以下検証コード

use strict;
use warnings;
use Benchmark;

timethese(100000, {
'overload' => sub { TestOverload->new },
'not overload' => sub { TestNoverload->new },
});

package TestNoverload;
sub new { bless { hoge => 'hoge' }, shift }

package TestOverload;
use overload (
q{""} => sub {},
);
sub new { bless { hoge => 'hoge' }, shift }

このコードをCentOSで動かすと
$ perl ./overload.pl 
Benchmark: timing 100000 iterations of not overload, overload...
not overload: 0 wallclock secs ( 0.17 usr + 0.00 sys = 0.17 CPU) @ 588235.29/s (n=100000)
(warning: too few iterations for a reliable count)
overload: 1 wallclock secs ( 0.86 usr + 0.00 sys = 0.86 CPU) @ 116279.07/s (n=100000)

FreeBSDで動かすと

$ perl /tmp/overload.pl 
Benchmark: timing 100000 iterations of not overload, overload...
not overload: 1 wallclock secs ( 0.47 usr + 0.00 sys = 0.47 CPU) @ 213333.33/s (n=100000)
overload: 0 wallclock secs ( 0.46 usr + 0.00 sys = 0.46 CPU) @ 216949.15/s (n=100000)
と、差は一目瞭然です。

他のOSでもCentOS程の差が見られませんでした。

話題のパッチを深追いしてみたところ、perl-5.8.8-U27512.patchは、perlのoverloadあたりのコードに手を加えていて

This is a hack cope with reblessing from class with overloading magic to
one without (or the other way). Search for every reference pointing to the
object. Can't use S_visit() because we would need to pass a parameter to
our function.
とか書いてあって、斜め訳すると「overloadされたクラスをblessする時に、全部のリファレンスを探索するよ。」って感じですか?

perl-5.8.8-U27509.patchの方は、overloadのテストをTest::Moreでやりたかっただけ?
それともperl coreへのpatchをあてたら元のtest通らなくなった?
調べてない。

とにかく、はてなでもFemoでも該当のパッチを除いても平気という実績はある感じなので、うちもpatchを外してrpm作り直した。
そしたらアプリケーションが6割スピードアップしたよママン;;

Posted by Yappo at 2007年06月11日 21:31 | TrackBack | Perl
Comments

はじめまして、hkoba と申します。

件のパッチの影響ですが、 6倍どころでは済まないようです。

new 結果を配列に残すように変えると、私のマシンでは n=100000 で 1000倍以上の差が出ます。(n の数に対してノンリニアに遅くなります)

http://buribullet.net/svntrac/buribullet/wiki?p=Fedora%E3%81%AEPerl%E3%81%8C%E9%81%85%E3%81%84%E4%BB%B6

ご参考まで…

Posted by: hkoba at 2007年06月20日 07:52
Post a comment









Remember personal info?






コメントを投稿する前に↓の場所にnospamと入力してください。