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

Posted

技术标签:

【中文标题】如果我的代码中没有诊断信息,为啥 Perl 会编译 diagnostics.pm?【英文标题】:Why does Perl compile diagnostics.pm if I have no diagnostics in my code?如果我的代码中没有诊断信息,为什么 Perl 会编译 diagnostics.pm? 【发布时间】:2012-11-26 14:34:06 【问题描述】:

当我查看 Devel::NYTProf v4 的输出以获取 CGI program 时,我在报告中遇到了 diagnostics.pmSource Code Files — 按专有时间然后名称排序

首先我不明白为什么会在生产代码中。我深入挖掘了报告,发现它是由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 毫秒的时间。

perldoc useno 关键字的评价如下:

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

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

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

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

BEGIN 
  require diagnostics.pm;
  diagnostics->unimport;

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

【问题讨论】:

在任何人指出之前:我并没有尝试优化任何东西(还),我只是想了解被调用的内容。 【参考方案1】:

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

是的。它确实完全等同于

BEGIN 
  require diagnostics;
  diagnostics->unimport;

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

【讨论】:

在“普通”情况下,模块已经加载,因为你 used 它在某个地方,所以 require 是无操作的,只有 unimport 重要。但是是的,假设该模块在之前的任何时候都不是required,no 会这样做。

以上是关于如果我的代码中没有诊断信息,为啥 Perl 会编译 diagnostics.pm?的主要内容,如果未能解决你的问题,请参考以下文章

Perl:为啥在循环中声明(我的)变量会更慢?

默认情况下为啥没有设置线程化 perl(带有 usethreads)?

为啥 STDIN 会导致我的 Perl 程序冻结?

如果我的代码中没有“静态”,为啥会出现错误 CS0120?

如果我已经创建了一个序列化程序集,为啥代码会编译一个序列化程序集?

如何有条件地将 C 代码片段编译到我的 Perl 模块?