开发者

why are sub routine arguments slower to use than outer variables?

Running the following code :

use strict;
use warnings;
use Benchmark;

my $defaultArray = [1,2,3,4];
sub VARIABLE {
  my $arrayref =  @_ ? $_[0] : $defaultArray;
  return $arrayref->[0].$arrayref->[1].$arrayref->[2].$arrayref->[3];
}

Benchmark::cmpthese(
  -10,
  {
    VARIABLE_DEFAULT => sub { VARIABLE() },
    VARIABLE_NODEFAULT => sub { VARIABLE([4,3,2,1]) },
  }
);

I get the following Benchmark results :

                            Rate VARIABLE_NODEFAULT   VARIABLE_DEFAULT
VARIABLE_NODEFAULT  313631/s                 --               -74%
VARIABLE_DEFAULT   1210501/s               286%                 --

Why is the NODEFAULT version so much slower than 开发者_C百科the DEFAULT one ?


It's that much slower because you're creating a new anonymous array ref every time you call it. Change the code to this:

use strict;
use warnings;
use Benchmark;

my $defaultArray = [1,2,3,4];
sub VARIABLE {
  my $arrayref =  @_ ? $_[0] : $defaultArray;
  return $arrayref->[0].$arrayref->[1].$arrayref->[2].$arrayref->[3];
}

Benchmark::cmpthese(
  -10,
  {
    VARIABLE_DEFAULT => sub { VARIABLE() },
    VARIABLE_NODEFAULT => sub { VARIABLE($defaultArray) },
  }
);

And your benchmark ends up much nicer:

                        Rate VARIABLE_NODEFAULT   VARIABLE_DEFAULT
VARIABLE_NODEFAULT 1065824/s                 --                -2%
VARIABLE_DEFAULT   1085082/s                 2%                 --


I'd say because DEFAULT uses one and the same array for every call while the NODEFAULT has to allocate and free space for the array for every call. Compare with the following:

Benchmark::cmpthese(
  -10,
  {
    VARIABLE_DEFAULT => sub { VARIABLE() },
    VARIABLE_NODEFAULT => sub { VARIABLE($defaultArray) },
  }
);
                        Rate VARIABLE_NODEFAULT   VARIABLE_DEFAULT
VARIABLE_NODEFAULT 1619427/s                 --                -4%
VARIABLE_DEFAULT   1689428/s                 4%                 --


Got it. This is not the use of a parameter instead of an outer variable, but the test himself : VARIABLE_NODEFAULT => sub { VARIABLE([4,3,2,1]) } In this line, we create an array. Not in this one : VARIABLE_DEFAULT => sub { VARIABLE() },.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜