Question

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 the DEFAULT one ?

Was it helpful?

Solution

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%                 --

OTHER TIPS

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() },.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top