почему аргументы подпрограммы медленнее, чем внешние переменные? - PullRequest
1 голос
/ 25 ноября 2010

Запуск следующего кода:

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]) },
  }
);

Я получаю следующие результаты теста:

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

Почему версия NODEFAULT намного медленнее, чем версия DEFAULT?

Ответы [ 3 ]

4 голосов
/ 25 ноября 2010

Это намного медленнее, потому что вы создаете новый анонимный массив ref каждый раз, когда вызываете его. Измените код на это:

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) },
  }
);

И ваш тест в конечном итоге гораздо приятнее:

                        Rate VARIABLE_NODEFAULT   VARIABLE_DEFAULT
VARIABLE_NODEFAULT 1065824/s                 --                -2%
VARIABLE_DEFAULT   1085082/s                 2%                 --
4 голосов
/ 25 ноября 2010

Я бы сказал, потому что DEFAULT использует один и тот же массив для каждого вызова, а NODEFAULT должен выделять и освобождать пространство для массива для каждого вызова.Сравните со следующим:

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%                 --
1 голос
/ 25 ноября 2010

Понял. Это не использование параметра вместо внешней переменной, а сам тест: VARIABLE_NODEFAULT => sub { VARIABLE([4,3,2,1]) } В этой строке мы создаем массив. Не в этом: VARIABLE_DEFAULT => sub { VARIABLE() },.

...