startup.plに書いておいた方が良い事。

わたくしMy三国志というサイトをmod_perl+Apacheでやってるんですが、やはりネックになるのがメモリです。やりくりにはいわるゆるstartup.plの最適化が必須という事で結構色々やってます。結構、枯れてる話題で色んな情報が転がっていますが、参考までに当サイトでやっている事を挙げてみました。

ローカルのモジュールをくまなくrequireし取りこぼしを減らす

サイト用のモジュールのパッケージ名をベッタ〜とstartup.plに書いてたんですが、モジュールを追加したり、削除したりいくうちにstartup.plのメンテナンスが追いつかなくなってきました。こりゃいかんという事でもう一発で読み込んでしまおうという事で次のように書いてます。

use File::Find ();

my $lib_root = "モジュールのあるディレクトリ";
File::Find::find(sub {
    my $name = $File::Find::name;
    return if -d $name;
    return if $name !~ /\.pm$/;
    $name =~ s/^$lib_root\///;
    $name =~ s/^$lib_root//;
    require $name;
}, $lib_root);

$lib_rootを消しているのは$File::Find::nameがフルパスで返してくるからです。例えば/usr/local/lib/My3594.pmというモジュールが有る場合、そのままだと%INCでは下記のように突っ込まれてます。

'My3594.pm' => '/usr/local/lib/My3594.pm',

しかしPERL5LIBに/usr/local/libが通っている場合上以下の形で%INCに突っ込まれます。

'My3594.pm' => 'My3594.pm',

ここでredfiened警告が出てしまうので、パスを揃えるためにlibまでのパスを消しているのです。まぁ当サイト固有の話なかもしれませんが恐らく皆様そんな感じじゃないかしら。

動的に読み込まれるモジュールに対する対処

遅延ロードされるモジュールについてはuseとかrequireしただけでは、動的に読み込まれるモジュールについてはメモリ上にロードされません。という訳で色々ぶらさがってそうなモジュールの処理を一回流してみる、というのをやってます。

TemplateToolkit
一通り色々やってみてる処理を流してます。

use Template ();
my $template = qq/
[%- USE Class('Data::Page') -%]
[%- USE JavaScript -%]
[% hoge | html | js %]
/;
Template->new()->process(\$template, {hoge => 'hoge'}, \my $out) or die;

LWP::UserAgent
getまで一回やってみます。

use LWP::UserAgent;
my $lwp = LWP::UserAgent->new(agent => 'My3594/1.0', timeout => 3);
my $res = $lwp->get("http://feeds.feedburner.jp/my3594-pedia-new_entry");

Class::DBIのサブクラス
retrieveしたりsearchしたり・・・半分おまじないですw

use My3594::Data::Member;
My3594::Data::Member->retrieve(1);
my @list = My3594::Data::Member->search(id => 1);
my $list = My3594::Data::Member->search(id => 1);
@list = My3594::Data::Member->retrieve_from_sql(q/id = 1/);
$list = My3594::Data::Member->retrieve_from_sql(q/id = 1/);

この辺のチェックについては下記のINCDiff.pmを活用させていただいております。
http://d.hatena.ne.jp/hideden/20080409/1207740439


さてさて後何ができるだろうか・・・。