首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用mod_perl时,如何仅在编译时执行效率低下的代码?

在使用mod_perl时,如何仅在编译时执行效率低下的代码?
EN

Stack Overflow用户
提问于 2008-12-04 23:42:29
回答 6查看 475关注 0票数 9

我一直在对我用Perl编写的框架的性能进行基准测试,与现有的代码库相比,每秒的请求减少了50% (有些命中是可以理解的,因为我们正在从过程式的意大利代码转向OOP MVC框架)。

应用程序是在mod_perl下运行的,我已经将驼鹿和所有框架代码添加到startup.pl脚本中,这本身使我的请求每秒增加了一倍。我希望进一步提高这个数字,使它尽可能接近现有的数量。理由是,这是不成熟的优化,但有几个明显的低效率,我想解决,看看它如何影响性能。

与大多数框架一样,我有一个配置文件和一个dispatcher。配置部分由配置::General处理,因此需要进行一些IO和解析,以便将我的配置文件加载到应用程序中。我在这里看到的最大的问题是,我是为每一个请求都这样做的!

运行Devel::Dprof在我的应用程序中指向Config::General::BEGIN和一堆相关的IO模块,它们不是Moose的主要慢点之一。因此,我想要做的,以及事后看来更有意义的是,利用mod_perl的持久性和startup.pl编译功能,只做一次在配置文件中加载的工作--当服务器启动时。

问题是我不太熟悉它的工作原理。

目前,每个项目都有一个PerlHandler引导类,它非常精简,如下所示:

代码语言:javascript
复制
use MyApp; 
MyApp->new(config_file => '/path/to/site.config')->run();

MyApp.pm继承了framework模块,该模块具有以下代码:

代码语言:javascript
复制
my $config = Config::General->new(
                -ConfigFile => $self->config_file,
                -InterPolateVars => 1,
             );    

$self->config({$config->getall});

只有在编译时才能做到这一点,我的引导程序和Project模块都必须改变(我认为),但是我不确定要做哪些更改,并且仍然保持代码的简洁性。有人能指出我的正确方向吗?

更新

我在每个项目模块方法中尝试了BEGIN块,这是由ysth在他的回答中描述的。所以我现在有:

代码语言:javascript
复制
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块中,只有配置文件的路径不同。我有几个不同的策略来限制这一点,但我只是想发布这一变化的结果。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2008-12-04 23:55:28

假设应用程序根本不更改配置,则将其移动到begin块中:

代码语言:javascript
复制
# this code goes at file scope
my $config;
BEGIN {
    $config = { Config::General->new( ... )->getall }
}

# when creating a new instance
$self->config( $config );

并确保您的所有模块都是用startup.pl编译的。

您可以获得更好的配置,并让一个单例类提供配置哈希,但不需要这样做。

票数 10
EN

Stack Overflow用户

发布于 2008-12-05 13:13:51

如果你能使你的驼鹿类不可变的,这可能会给你另一个减速带。

票数 4
EN

Stack Overflow用户

发布于 2009-07-16 16:14:29

模块的进口分是在编译时执行的,因此我们可以使用它来减少/消除ysth的回答的枯燥。

在下面的示例中,我们使用导入方法读取配置文件,并给出参数,然后将该配置推入调用包中。

调用包中任何$config变量的警告都将被删除。

代码语言:javascript
复制
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'; 
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/342468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档