25

当我查看CGI 程序的Devel::NYTProf v4的输出时,我在报告Source Code Files 中遇到了- 按独占时间排序,然后按名称排序diagnostics.pm

诊断.pm

首先,我不明白为什么会出现在生产代码中。我深入研究了报告,发现它是由main::BEGIN@17. 反过来,这就是以下行:

# spent 34µs (26+8) within main::BEGIN@15 which was called: # once (26µs+8µs) by main::RUNTIME at line 15
use strict;
# spent 34µs making 1 call to main::BEGIN@15 # spent 8µs making 1 call to strict::import

# spent 36µs (17+19) within main::BEGIN@16 which was called: # once (17µs+19µs) by main::RUNTIME at line 16
use warnings;

# spent 36µs making 1 call to main::BEGIN@16 # spent 19µs making 1 call to warnings::import

# spent 292ms (171+121) within main::BEGIN@17 which was called: # once (171ms+121ms) by main::RUNTIME at line 17
no diagnostics;
# spent 292ms making 1 call to main::BEGIN@17

# spent 135µs (27+108) within main::BEGIN@18 which was called: # once (27µs+108µs) by main::RUNTIME at line 18
use Carp qw( carp croak );

所以这似乎是罪魁祸首。我拔掉了no diagnostics线路,电话就没有了,有效地节省了大约 300 毫秒的时间。

以下是perldocuse关于no关键字的说明:

有一个相应的 no 声明 unimports 使用导入的含义,即它调用 unimport Module LIST 而不是 import。它的行为与 import 对 VERSION、省略或空 LIST 或未找到 unimport 方法的行为一样。

no integer;
no strict 'refs';
no warnings;

所以这是我的实际问题:我是否正确假设如果我调用no diagnostics,它实际上是在unimported 之前加载的?

调用no diagnostics类似于这段代码吗?

BEGIN {
  require diagnostics.pm;
  diagnostics->unimport;
}

因此,仅取消导入从未导入的东西是不是一个坏主意,因为这实际上首先加载了它?

4

1 回答 1

22

我是否正确假设如果我调用no diagnostics,它实际上是在未导入之前加载的?

是的。它确实完全等同于

BEGIN {
  require diagnostics;
  diagnostics->unimport;
}

所以no module命令实际加载并编译模块;包括执行不在任何sub、 BEGIN 块等中的代码;对于给定模块的所有依赖项都相同(对于内部的每次使用/需要)。

于 2012-11-26T14:38:06.217 回答