在Perl中,"我的"比"本地"更快?

Laz*_*zer 12 perl

引自PerlMonks:我和本地的区别,

但在现实生活中,它们的工作方式几乎相同?是.有点.那么什么时候应该使用它们?

尽可能使用我(它比本地更快)......

我知道mySO之间的词法与动态范围的区别local,正如在这个SO线程中讨论的那样,但我不确定为什么my"更快".

当我们说my变量比localPerl 中的变量更快时,我们究竟是什么意思?

Eth*_*her 19

使用local一个变量意味着以前的状态需要再次某处入栈和恢复时,局部范围内退出.使用my一个变量简单地创建阴影具有相同名称的一个变量一个全新的变量-前一个是完全不变,并且不需要在任何地方保存.当局部范围退出并再次可见时,它只是在等待.

这种推送/弹出到堆栈需要资源; 在引擎盖下有很多工作要确保它正常工作.(考虑一些情况,例如在本地范围内抛出异常,或者执行信号处理程序.我相信你能想到更多.)

除了提高效率外,使用my更合乎逻辑.作为一个程序员引入一个局部变量$ foo的,你不必担心语义原因以前版本的$ foo的,什么样的数据可能已经在里面,或者事实上,如果有已经创建了$ foo的.如果在某个时候,$ foo的早期声明被删除,你的local $foo代码将会中断,但my $foo会非常高兴.成为一名优秀的程序员并将代码保存在封装良好的部分中,这意味着尽可能多地使用词法作用域.编写一个大型应用程序并且根本不需要包/全局范围的变量是非常可能的,特别是当您使用设计良好的OO类时.

  • 具体来说,有一个"词法便笺簿"已经为每个词汇范围分配,Perl将新词汇放在上面.当示波器退出时,便笺本会消失.此外,local()必须处理各个哈希和数组元素的本地化和恢复(`local $ h {key}`).最后,绑定变量由local进行特殊处理,它们的FETCH和STORE方法在被本地化和恢复时被调用.任何必须考虑绑定的东西都比较慢,因为它必须检查变量是否绑定. (8认同)
  • @Evan Carroll:不,它使用了一个名为savestack的堆栈 (3认同)

Cha*_*ens 12

local可能因为需要保存旧值而变慢,但localvs 的速度my根本不应该进入讨论.节省的速度是微不足道的:

           Rate local    my
local 7557305/s    --   -2%
my    7699334/s    2%    --
Run Code Online (Sandbox Code Playgroud)

两者的特征完全不同.以上结果来自以下基准:

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark;

our $x;

my %subs = (
    local => sub {
        local $x = 42;
        return $x;
    },
    my => sub {
        my $x = 42;
        return $x;
    }
);

for my $sub (keys %subs) {
    print "$sub: ", $subs{$sub}(), "\n";
}

Benchmark::cmpthese -1, \%subs;
Run Code Online (Sandbox Code Playgroud)

  • 当你介绍Schwern在我的回答中描述的一些案例时,速度差异会变得更加明显. (3认同)