是什么导致perl导入模块的速度非常慢?

时间:2015-03-31 12:07:08

标签: solaris perl cgi bugzilla

我正在将我们团队的bugzilla升级到最新的稳定版本。 在以前使用过的Bugzilla 2.x中,网页的加载时间大约是2秒,用户已经接受了。但是Bugzilla 4.4.8需要3到4秒来渲染页面。 我的问题是perl似乎在导入Bugzilla所需模块时遇到问题。

我通过直接用perl检查index.cgi脚本来解决这个问题,编写一个testscript.cgi,它只导入perl Bugzilla模块,并通过一个接一个地注释掉use语句来检查导致长运行时间的原因。

#!/usr/bin/perl

use strict;
use lib qw(. lib);
use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Update;

print "Content-Type: text/html\n\n";
print "<html><body>\n";

foreach (@INC){
   print "$_<br>\n";
}

print "</body></html";

在禁用Bugzilla导入时,服务器响应时间将缩短至50毫秒。 我继续将它与我笔记本上的本地Perl / Apache / Bugzilla安装进行比较:〜630ms来呈现我可以接受的页面。

这种困难行为的可能起源出现在我的脑海中:如果必须遍历模块的过多目录怎么办?

Solaris机器@INC:

.
lib/sun4-solaris
lib
/opt/perl-5.20.2/lib/site_perl/5.20.2/sun4-solaris
/opt/perl-5.20.2/lib/site_perl/5.20.2
/opt/perl-5.20.2/lib/site_perl/sun4-solaris
/opt/perl-5.20.2/lib/site_perl

Notebook @INC:

.
lib/i686-linux-gnu-thread-multi-64int
lib
/etc/perl
/usr/local/lib/perl/5.18.2
/usr/local/share/perl/5.18.2
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.18
/usr/share/perl/5.18
/usr/local/lib/site_perl

导致服务器上导入perl模块的长运行时间是什么原因? 我怎样才能测量IO读取时间?

系统属性:

Perl 5.20.2 / Solaris 10

更新 正如评论中所建议的那样,我使用Devel :: NYTProf分析了脚本:脚本花费大部分时间来处理几个文件中的以下语句

use Bugzilla::Install::Filesystem
use Bugzilla::Install::Localconfig
use Bugzilla::Install::Util
use Bugzilla::Auth and subroutines
use Bugzilla::User
use Bugzilla::Template

1 个答案:

答案 0 :(得分:0)

这不是一个完整的答案,但是要通过gabby进行评论。

您使用的是一个PATH变量。当您搜索路径时,系统会打开(使用opendir())每个目录,然后尝试打开/统计它找不到的任何文件。这对于大量的大目录来说效率可能不高。

具体实施可能因平台而异。我已经看到了更有效地使用stat。您可以在Solaris中使用truss:

看到这一点

假设testscript.cgi有一个shebang尝试打开系统调用:

truss -t open testscript.cgi

请注意ENOENT错误,因为找不到文件。

尝试统计

truss -t stat testscript.cgi

ENOENT同上 - 可以说是stat64

我所知道的唯一解决方案并不是很好 - 创建一个特殊的目录。 如果没有nomen confusum条目,则将符号链接添加到pm文件 - 不同包的重复项。如果有多个条目说foo.pm,你可能会遇到问题。此示例仅使用pm条目。 我只熟悉perl 5.8及更早版本。您需要修改它以适应正在发生的事情。因此@INC将具有基本perl路径和一个或两个特殊目录。

在遇到这些麻烦之前,请确保您的Solaris inode缓存已足够。

我能做的最好。其他人可能有更好的解决方案。