如果我的代码中没有诊断,为什么Perl会编译diagnostics.pm?

sim*_*que 25 perl devel-nytprof

当我查看Devel :: NYTProf v4 的输出以获得CGI程序时,我遇到diagnostics.pm了报告源代码文件 - 按专用时间排序然后命名.

diagnostics.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 );
Run Code Online (Sandbox Code Playgroud)

所以这似乎是罪魁祸首.我删除了no diagnostics线路,呼叫消失了,有效地节省了大约300毫秒的时间.

以下是perldocuseno关键字的说法:

有一个相应的no声明,即使用导入的无意义含义,即它调用unimport Module LIST而不是import.它的行为就像使用VERSION,省略或空LIST或没有找到任何非导入方法一样.

no integer;
no strict 'refs';
no warnings;
Run Code Online (Sandbox Code Playgroud)

所以这是我的实际问题:我是否正确地假设如果我打电话no diagnostics,它实际上是在加载之前加载的unimport

no diagnostics这个代码的调用是否类似?

BEGIN {
  require diagnostics.pm;
  diagnostics->unimport;
}
Run Code Online (Sandbox Code Playgroud)

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

PSI*_*Alt 22

我是否正确假设如果我打电话no diagnostics,它实际上是在没有进入之前加载的?

是.它确实相当于

BEGIN {
  require diagnostics;
  diagnostics->unimport;
}
Run Code Online (Sandbox Code Playgroud)

所以no module命令实际上加载并编译模块; 包括执行这是不是在任何的代码,在BEGIN块等; 对于给定模块的所有依赖性(对于每个use/require inside)都是相同的.

  • 在"普通"的情况下,该模块已经加载,因为你`某处use`d它,所以`require`是一个空操作,只有`unimport`事项.但是,是的,假设模块在之前的任何时候都没有"要求","否"将会这样做. (4认同)