我一直在对我用Perl编写的框架的性能进行基准测试,与现有的代码库相比,每秒的请求减少了50% (有些命中是可以理解的,因为我们正在从过程式的意大利代码转向OOP MVC框架)。
应用程序是在mod_perl下运行的,我已经将驼鹿和所有框架代码添加到startup.pl脚本中,这本身使我的请求每秒增加了一倍。我希望进一步提高这个数字,使它尽可能接近现有的数量。理由是,这是不成熟的优化,但有几个明显的低效率,我想解决,看看它如何影响性能。
与大多数框架一样,我有一个配置文件和一个dispatcher。配置部分由配置::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继承了framework模块,该模块具有以下代码:
my $config = Config::General->new(
-ConfigFile => $self->config_file,
-InterPolateVars => 1,
);
$self->config({$config->getall});只有在编译时才能做到这一点,我的引导程序和Project模块都必须改变(我认为),但是我不确定要做哪些更改,并且仍然保持代码的简洁性。有人能指出我的正确方向吗?
更新
我在每个项目模块方法中尝试了BEGIN块,这是由ysth在他的回答中描述的。所以我现在有:
package MyApp::bootstrap;
use MyApp;
my $config;
BEGIN
{
$config = {Config::General->new(...)->getall};
}
sub handler { ..etc.
MyApp->new(config => $config)->run();仅这一快速更改就使我的请求每秒增加了50%的,这证实了我认为配置文件是一个值得修复的主要瓶颈。在我们古怪的旧开发机器上,基准值是60 has,仅在这个变化的情况下,我的框架就从30 has变成了45 has。对于那些说驼鹿速度慢并且有编译时间的人..。我得到了相同的(50%)的增加,当我的所有Moose代码在启动时,我做了从预编译我的配置文件。
我现在唯一的问题是,这违反了DRY主体,因为相同的config::General->新代码在每个BEGIN块中,只有配置文件的路径不同。我有几个不同的策略来限制这一点,但我只是想发布这一变化的结果。
发布于 2008-12-04 23:55:28
假设应用程序根本不更改配置,则将其移动到begin块中:
# this code goes at file scope
my $config;
BEGIN {
$config = { Config::General->new( ... )->getall }
}
# when creating a new instance
$self->config( $config );并确保您的所有模块都是用startup.pl编译的。
您可以获得更好的配置,并让一个单例类提供配置哈希,但不需要这样做。
发布于 2008-12-05 13:13:51
如果你能使你的驼鹿类不可变的,这可能会给你另一个减速带。
发布于 2009-07-16 16:14:29
模块的进口分是在编译时执行的,因此我们可以使用它来减少/消除ysth的回答的枯燥。
在下面的示例中,我们使用导入方法读取配置文件,并给出参数,然后将该配置推入调用包中。
调用包中任何$config变量的警告都将被删除。
package Foo_Config;
use English qw(-no_match_vars);
sub import {
my ($self, @cfg) = @ARG;
my $call_pkg = caller;
my $config = {Config::General->new(@cfg)->getall};
do{ # this will create the $config variable in the calling package.
no strict 'refs';
${$call_pkg . '::config'} = $config;
};
return;
}
package MyApp;
# will execute Foo_Config->import('/path/to/site.config') at compile time.
use Foo_Config '/path/to/site.config'; https://stackoverflow.com/questions/342468
复制相似问题