Performance 为什么使用$迭代需要更长的时间

Performance 为什么使用$迭代需要更长的时间,performance,perl,foreach,Performance,Perl,Foreach,基于互联网上的许多书籍,我想知道$是否真的是遍历数组的更快的方法(没有实例化新变量),但不知何故,我总是得到不同的结果。下面是性能代码测试: #!/usr/bin/perl use Time::HiRes qw(time); use strict; use warnings; # $_ is a default argument for many operators, and also for some control structures. my $test_array = [1..10

基于互联网上的许多书籍,我想知道$是否真的是遍历数组的更快的方法(没有实例化新变量),但不知何故,我总是得到不同的结果。下面是性能代码测试:

#!/usr/bin/perl
use Time::HiRes qw(time);

use strict;
use warnings;

# $_ is a default argument for many operators, and also for some control structures.

my $test_array = [1..1000000];

my $number_of_tests = 100;
my $dollar_wins = 0;
my $dollar_wins_sum = 0;

for (my $i = 1; $i <= $number_of_tests; $i++) {
    my $odd_void_array = [];
    my $start_time_1 = time();
    foreach my $item (@{$test_array}) {
        if ($item % 2 == 1) {
            push (@{$odd_void_array}, $item);
        }
    }
    foreach my $item_odd (@{$odd_void_array}) {
    }
    my $end_time_1 = time();

    $odd_void_array = [];
    my $start_time_2 = time();
    foreach (@{$test_array}) {
        if ($_ % 2 == 1) {
            push (@{$odd_void_array}, $_);
        }
    }
    foreach (@{$odd_void_array}) {
    }
    my $end_time_2 = time();

    my $diff = ($end_time_1-$start_time_1) - ($end_time_2-$start_time_2);
    if ($diff > 0) {
        $dollar_wins ++;
        $dollar_wins_sum += $diff;
        print "Dollar won ($dollar_wins out of $i) with diff $diff \n";
    }
}

print "=================================\n";
print "When using dollar underscore, execution was faster in $dollar_wins cases (".(($dollar_wins/$number_of_tests)*100)."%), with average difference of ".($dollar_wins_sum/$dollar_wins)."\n";
#/usr/bin/perl
使用时间:雇佣qw(时间);
严格使用;
使用警告;
#$\是许多运算符以及某些控件结构的默认参数。
我的$test_数组=[1..1000000];
我的$number_of_测试=100;
我的$dollar_赢=0;
我的$dollar\u赢了\u sum=0;
对于(我的$i=1;$i 0){
$dollar_赢得++;
$dollar\u赢了\u sum+=$diff;
用diff$diff\n打印“美元赢($i中的美元赢”);
}
}
打印“=======================================================\n”;
打印“使用美元下划线时,$dollar\U wins案例中的执行速度更快(($dollar\U wins/$number\U of\U测试)*100)。”%,平均差异为“($dollar\U wins\U sum/$dollar\U wins)。”\n;
因此,我有两次迭代(一次分配给$item,另一次不分配)。我得到的主要信息是,在大约20-30%的情况下,使用$迭代的速度更快


在没有新变量的情况下,是否应该加快迭代速度?

您并不是在用不同的变量对迭代进行基准测试

  • 计时包括阵列创建和其他计算
  • 你只知道哪一个更快,而不是多少
  • 您的迭代次数太少,无法说出任何可靠的信息
让我们做一个更好的测试,实际测试您声称的基准测试:

use strict;
use warnings;
use Benchmark ':hireswallclock', 'cmpthese';

my @numbers = 1..100_000;

cmpthese -3, {
  '$_' => sub {
    for (@numbers) {
      1;
    }
  },
  'my $x' => sub {
    for my $x (@numbers) {
      1;
    }
  },
  '$x' => sub {
    my $x;
    for $x (@numbers) {
      1;
    }
  },
}
结果:

       Rate    $_ my $x    $x
$_    107/s    --   -0%   -0%
my $x 107/s    0%    --   -0%
$x    108/s    0%    0%    --
因此,在我的测试系统(为i686-linux-thread-multi-64int构建的Perl5.18.2)上,它们的速度同样快

我的怀疑是,使用
$\uu
比词法略慢,因为它是一个全局变量。然而,迭代的速度是相等的。事实上,修改基准

use strict;
use warnings;
use Benchmark ':hireswallclock', 'cmpthese';

my @numbers = 1..100_000;

cmpthese -3, {
  '$_' => sub {
    for (@numbers) {
      $_ % 2 == 0;
    }
  },
  'my $x' => sub {
    for my $x (@numbers) {
      $x % 2 == 0;
    }
  },
  '$x' => sub {
    my $x;
    for $x (@numbers) {
      $x % 2 == 0;
    }
  },
}
…给予

        Rate    $_    $x my $x
$_    40.3/s    --   -1%   -6%
$x    40.6/s    1%    --   -5%
my $x 42.9/s    7%    6%    --

但影响仍然太小,无法得出任何可靠的结论。

sa$je onda brze ili sporije?它实际上没有将值复制到变量中。测试这个:perl-e'@a=(1,2,3);$z++foreach(@a);打印@a;'您将看到它更新了@a。它实际上将列表中的变量别名为您定义的名称。这可能会影响性能。让我翻译一下@mpapec的问题:)“那么,是快了还是慢了呢?”我说,根据我的发现,$慢了……我只是想知道这是怎么回事?:)foreach变量总是使用别名,而不管
$\uuu0>或其他变量的用法如何。它与
的用法并不一致。我得到的主要结论是,在大约20-30%的情况下,使用$\u0进行迭代的速度更快。
:)词典的性能确实应该比包变量稍微好一些,但我找不到任何关于这种说法的参考。@mpapec请看一些带有
-MO=concrete
的简单片段。使用global本质上是在stash中进行查找(这只是将名称映射到glob的一种特殊散列)。词典是在pad(本质上是一个数组)上查找的。除了可能的缓存效应外,这本身使词汇更快。但在实践中,差别很小。词汇的其他方面更为重要(主要是它们的作用域优势)。这仅仅是从Perl访问它的方式。词汇基本上是在一个2D数组中(想想递归)。(不确定“pad”是指整个事物,还是仅指第二维度。)如果将
@numbers
数组更改为
1..2
,而不是
1..100_000
,则差异会变得更加明显;词汇可以快10%。