我在Perl中是个新手,我想知道以下哪个循环更有效:

my @numbers = (1,3,5,7,9);
foreach my $current (@numbers){
    print "$current\n";
}

或者
my @numbers = (1,3,5,7,9);
foreach (@numbers){
    print "$_\n";
}

我想知道这一点,以便知道$ _的使用是否更有效,因为它是否经常使用而被放置在寄存器中。我已经编写了一些代码,并且试图对其进行清理,发现与第二个循环相比,我使用第一个循环的频率更高。

最佳答案

甚至知道过早的优化是万恶之源

{
  local $\ = "\n";
  print foreach @numbers;
}

但有些期望可能是错误的。测试有点怪异,因为输出可能会产生一些怪异的副作用,而顺序可能很重要。
#!/usr/bin/env perl
use strict;
use warnings;
use Benchmark qw(:all :hireswallclock);

use constant Numbers => 10000;

my @numbers = (1 .. Numbers);

sub no_out (&) {
    local *STDOUT;
    open STDOUT, '>', '/dev/null';
    my $result  = shift()->();
    close STDOUT;
    return $result;
};

my %tests = (
    loop1 => sub {
        foreach my $current (@numbers) {
            print "$current\n";
        }
    },
    loop2 => sub {
        foreach (@numbers) {
            print "$_\n";
        }

    },
    loop3 => sub {
        local $\ = "\n";
        print foreach @numbers;
        }
);

sub permutations {
    return [
        map {
            my $a = $_;
            my @f = grep {$a ne $_} @_;
            map { [$a, @$_] } @{ permutations( @f ) }
            } @_
        ]
        if @_;
    return [[]];
}

foreach my $p ( @{ permutations( keys %tests ) } ) {
    my $result = {
        map {
            $_ => no_out { sleep 1; countit( 2, $tests{$_} ) }
            } @$p
    };

    cmpthese($result);
}

可以预料到loop2应该比loop1更快
       Rate loop2 loop1 loop3
loop2 322/s    --   -2%  -34%
loop1 328/s    2%    --  -33%
loop3 486/s   51%   48%    --
       Rate loop2 loop1 loop3
loop2 322/s    --   -0%  -34%
loop1 323/s    0%    --  -34%
loop3 486/s   51%   50%    --
       Rate loop2 loop1 loop3
loop2 323/s    --   -0%  -33%
loop1 324/s    0%    --  -33%
loop3 484/s   50%   49%    --
       Rate loop2 loop1 loop3
loop2 317/s    --   -3%  -35%
loop1 328/s    3%    --  -33%
loop3 488/s   54%   49%    --
       Rate loop2 loop1 loop3
loop2 323/s    --   -2%  -34%
loop1 329/s    2%    --  -33%
loop3 489/s   51%   49%    --
       Rate loop2 loop1 loop3
loop2 325/s    --   -1%  -33%
loop1 329/s    1%    --  -32%
loop3 488/s   50%   48%    --

有时我始终观察到loop1loop2快15%-20%,但我无法确定原因。

观察到我为loop1和loop2生成了字节码,并且在创建my变量时只有一个区别。此可变内部空间不会分配,也不会被复制,因此此操作非常便宜。我认为差异仅来自"$_\n"构造,这并不便宜。这些循环应该非常相似
for (@numbers) {
  ...
}

for my $a (@numbers) {
  ...
}

但是这个循环更昂贵
for (@numbers) {
  my $a = $_;
  ...
}

并且
print "$a\n";


print $a, "\n";

10-04 16:28