我一直在对我用 Perl 编写的框架的性能进行基准测试,与我们现有的代码库相比,每秒请求数减少了 50%(有些命中是可以理解的,因为我们正在从程序化的意大利面条代码变为OOP MVC 框架)。
该应用程序在 mod_perl 下运行,我已将Moose和我所有的框架代码添加到startup.pl 脚本中,这本身使我每秒的请求量增加了一倍。我希望进一步提高这个数字,使其尽可能接近现有数量。有人认为这是过早的优化,但是我想解决一些明显的低效率问题,看看它是如何影响性能的。
像大多数框架一样,我有一个配置文件和一个调度程序。配置部分由Config::General处理,因此需要进行一些 IO 和解析才能将我的配置文件加载到应用程序中。我在这里看到的最大问题是我正在为每一个进来的请求做这个!
在我的应用程序上运行 Devel::Dprof 指向 Config::General::BEGIN 和一堆相关的 IO 模块作为不是 Moose 的主要慢点之一。所以我想做的,事后看来更有意义的是利用 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});
仅在编译时执行此操作,我的引导程序和项目基础模块都必须更改(我认为),但我非常不确定要进行哪些更改并且仍然保持代码的美观和精简。谁能在这里指出我正确的方向?
更新
我在每个项目模块方法中尝试了 BEGIN BLOCK,如 ysth 在他的回答中所述。所以我现在有:
package MyApp::bootstrap;
use MyApp;
my $config;
BEGIN
{
$config = {Config::General->new(...)->getall};
}
sub handler { ..etc.
MyApp->new(config => $config)->run();
仅这一快速更改就让我每秒的请求数增加了50% ,这证实了我的想法,即配置文件是一个值得修复的主要瓶颈。我们古怪的旧开发机器上的基准数字是 60rps,仅此更改,我的框架就从 30rps 变为 45rps。对于那些说 Moose 很慢并且编译时间很短的人。在启动时编译所有 Moose 代码时,我得到了与预编译我的配置文件时相同(50%)的增长。
我现在唯一的问题是这违反了 DRY 原则,因为相同的 Config::General->new 代码在每个 BEGIN 块中,只有配置文件的路径不同。我有一些不同的策略来限制这一点,但我只是想发布这种变化的结果。