私はPerlで書いているフレームワークのパフォーマンスをベンチマークしてきましたが、既存のコードベースに比べて1秒あたりのリクエスト数が50%減少しています(手続き型スパゲッティコードからOOP MVCフレームワーク)。
アプリケーションはmod_perlで実行されており、 Mooseとすべてのフレームワークコードをstartup.plスクリプトに追加しました。これにより、1秒あたりのリクエスト数が2倍になりました。この数をさらに増やして、既存の量にできるだけ近づけることを目指しています。これは時期尚早の最適化であるという議論がありますが、修正してパフォーマンスにどのように影響するかを確認したいいくつかの明白な非効率性があります。
ほとんどのフレームワークと同様に、構成ファイルとディスパッチャーがあります。構成部分はConfig::Generalによって処理されるため、構成ファイルをアプリにロードするには、少しのIOと解析が必要です。ここで私が目にする最大の問題は、入ってくるすべてのリクエストに対してこれを行っていることです。
私のアプリでDevel::Dprofを実行すると、Mooseではない主要な低速ポイントの1つとして、Config :: General::BEGINと関連するIOモジュールの束が示されます。だから私がやりたいこと、そして後から考えるともっと理にかなっているのは、mod_perlの永続性とstartup.plコンパイルのものを利用して、サーバーの起動時に一度だけ構成ファイルにロードする作業を行うことです。
問題は、これがどのように機能するかについて私があまりよく知らないということです。
現在、各プロジェクトには、かなり無駄のない、次のようなPerlHandlerブートストラップクラスがあります。
use MyApp;
MyApp->new(config_file => '/path/to/site.config')->run();
MyApp.pmは、次のコードを持つフレームワークProjectモジュールを継承します。
my $config = Config::General->new(
-ConfigFile => $self->config_file,
-InterPolateVars => 1,
);
$self->config({$config->getall});
コンパイル時にのみこれを行うには、ブートストラップとプロジェクトの両方のベースモジュールを変更する必要があります(私は思います)が、どのような変更を加えれば、コードを適切で無駄のないものに保つことができるかについてはかなりわかりません。誰かが私をここで正しい方向に向けることができますか?
アップデート
ysthの回答で説明されているように、各プロジェクトモジュールアプローチでBEGINBLOCKを試しました。だから私は今持っています:
package MyApp::bootstrap;
use MyApp;
my $config;
BEGIN
{
$config = {Config::General->new(...)->getall};
}
sub handler { ..etc.
MyApp->new(config => $config)->run();
この迅速な変更だけで、1秒あたりのリクエスト数が50%増加し、構成ファイルが修正する価値のある主要なボトルネックであるという私の考えを確認しました。私たちの股間の古い開発マシンのベンチマーク値は60rpsであり、この変更だけで私のフレームワークは30rpsから45rpsになりました。Mooseが遅く、コンパイル時間がヒットしていると言う人のために..起動時にすべてのMooseコードをコンパイルすると、構成ファイルを事前コンパイルしたときと同じ(50%)増加しました。
私が今抱えている唯一の問題は、同じConfig :: General-> newコードがすべてのBEGINブロックにあり、構成ファイルへのパスのみが異なるため、これがDRYプリンシパルに違反することです。これを制限するためのいくつかの異なる戦略がありますが、この変更の結果を投稿したかっただけです。