【问题标题】:Does "use ...." at the top add overhead to a Perl script?顶部的“use ....”是否会增加 Perl 脚本的开销?
【发布时间】:2010-11-02 11:38:03
【问题描述】:

我一直想知道这一点。我有一个总是添加的习惯

use strict;
use warnings;
use Data::Dumper;

到我写的每个脚本的顶部。如果我什至不使用 Dumper 功能,这会增加开销吗?此外,在大多数情况下,Data::Dumper 之前在另一个包中被调用过,但我在这个包中需要它,所以我再次包含它。在这种情况下会产生额外的开销吗?

【问题讨论】:

    标签: performance perl module


    【解决方案1】:

    这不是您所要求的,但我发现依赖 Data::Dumper 是一个拐杖,一个值得打破的习惯。由于 perl 遵循假定同伴代码是友好而不是恶意的理念,因此程序员很容易 Data::Dump 一个不透明的对象来发现它的内部是如何存储的,然后直接访问这些内部,而不是使用提供的接口。 Data::Dumper 是创建 Inside-Out 对象的原因之一——让敏锐但不耐烦的程序员更难/不可能通过内部结构四处寻找。

    【讨论】:

      【解决方案2】:

      如果你问你不介意。是的,它增加了一些开销。代码:

      use Data::Dumper;
      

      几乎完全等同于:

      BEGIN {
        require Data::Dumper;
        Data::Dumper->import();
      }
      

      这意味着,在编译时 Data::Dumper 模块被解析并执行主体,除非它还没有完成。这意味着如果您有许多模块并在每个模块中使用 Data::Dumper,则此开销仅发生一次。检查已经完成的要求非常快,真的非常快。第二行确实导入调用并将导入安装到当前包名称空间(由调用者获得)。在使用的所有模块中都需要一些时间。如果你想避免它使用:

      use Data::Dumper ();
      

      你不能打电话给Dumper(),但你必须使用Data::Dumper::Dumper()。我更喜欢使用Data::Dumper->Dump([vars], [names]),它给我带来了我更喜欢的输出。

      【讨论】:

        【解决方案3】:

        每次使用都会在脚本启动之前消耗时间,并且可能会增加脚本的内存占用。要测试开销,您可以运行以下脚本:

         C:\Temp> cat zzz.pl
         #!/usr/bin/perl
         sleep 10;
        
         C:\Temp> timethis zzz.pl
         TimeThis :  Elapsed Time :  00:00:10.172
        

        任务管理器中的内存占用为 2548K。

        现在添加

         use Data::Dumper;
        

        然后再次测试:

         TimeThis :  Elapsed Time :  00:00:10.266
        

        这一次,内存占用是 3408K。因此,如果您使用的模块没有真正使用,您会浪费一些时间和一些内存。

        在重复调用的脚本(如 CGI)中,启动时间很重要,而在长时间运行的脚本和脚本等情况下,内存占用很重要。

        【讨论】:

          【解决方案4】:

          如果您的脚本被重复执行并且存在延迟或运行时限制,这可能很重要。

          例如,如果它是一个每次呈现网页时分叉的进程,您可能希望通过删除未使用的模块来最大限度地减少在加载期间解析的代码量。

          或者,如果您在 xargs 的右侧运行 perl。

          还有其他方法可以消除 Web 服务器情况下的开销。

          【讨论】:

            【解决方案5】:

            Perl 必须解析Dumper.pm 中的代码,所以你的程序启动起来会比较慢。这通常对性能造成非常微不足道的影响。此外,任何不在函数或导入函数中的代码都将运行。这可能会对您的启动时间产生轻微影响。您还将消耗更多内存(代码的 AST 和代码构建的任何数据结构)。这不是你能做的最好的事情,但远非最糟糕的事情。除非您的程序非常频繁(一分钟多次),否则您应该不会注意到通过删除该行来真正提高速度。

            【讨论】:

              【解决方案6】:

              如果他们有BEGIN 块或import 例程,那么是的,它总是会增加开销。此外,任何主线代码最终都将被执行,任何INITCHECKEND 块也将执行。

              它不会增加开销的唯一方法是,如果模块期望userequire 无异。 (当然,require 运行除了import 例程之外的所有内容,但这就是为什么我提到来自use-d 模块的视图。它“期望”只是一个简单的require.)

              如果您出于某种原因想要保留该行,只需将其注释掉即可。在开发中,有你不使用的模块是可以的。在 QA 或生产中,这是一个错误,IMO。

              【讨论】:

              • 但是开发也应该尽可能地反映生产。我宁愿总是包含像 Data::Dumper 这样的东西,而不是只包含在开发中。
              • 当然,这就是为什么当你检查它时,它应该有“#use Data::Dumper;”在里面。由于您经常会在开发过程中进行更改,请取消注释该行,您就可以开始了。如果您希望它恢复到它在生产中的工作方式,请再次注释掉该行。
              猜你喜欢
              • 2012-03-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-03-26
              • 1970-01-01
              • 2010-12-28
              相关资源
              最近更新 更多