Эффективность между этими двумя объектами достаточно близка, и это затмевается любой реалистичной обработкой.Поэтому я бы пошел по коду –, если $tmp
действительно временный и ненужный после цикла, тогда лучше сохранить его внутри (область действия) по всем другим причинам.
Поскольку это касается оптимизации, я бы хотел отвлечься. Такие микро-проблемы могут иметь последствия. Однако, когда вы действительно выигрываете, это сначала на уровне алгоритмов, а затем путем выбора структур данных и методов соответствующим образом. Низкоуровневые настройки - это самое последнее, о чем нужно подумать, и часто есть языковые функции и библиотеки, которые делают их несущественными. Тем не менее, нужно знать инструмент, а не тратить время.
Кроме того, между ясностью и эффективностью кода часто существует компромисс. Если дело доходит до того, что я предлагаю закодировать правильность и ясность. Затем профиль и оптимизируйте при необходимости, осторожно и постепенно, и с большим количеством проверок между ними.
Просьба сравнить, как пример базового использования основного модуля Benchmark. Я делаю дополнительную операцию и добавляю другие случаи, когда нет временных.
use warnings 'all';
use strict;
use Benchmark qw(cmpthese);
my $x;
sub tmp_in {
for (1..10_000) {
my $tmp = 2 * $_;
$x = $tmp + $_;
}
return $x;
}
sub tmp_out {
my $tmp;
for (1..10_000) {
$tmp = 2 * $_;
$x = $tmp + $_;
}
return $x;
}
sub no_tmp {
for (1..10_000) { $x = 2 * $_ + $_ }
return $x;
}
sub base {
for (1..10_000) { $x += $_ }
return $x;
}
sub calc {
for (1..10_000) { $x += sin sqrt(rand()) }
return $x;
}
cmpthese(-10, {
tmp_in => sub { tmp_in },
tmp_out => sub { tmp_out },
no_tmp => sub { no_tmp },
base => sub { base },
calc => sub { calc },
});
выход (на v5.16)
Rate calc tmp_in tmp_out no_tmp base
calc 623/s -- -11% -26% -44% -59%
tmp_in 698/s 12% -- -17% -37% -54%
tmp_out 838/s 34% 20% -- -25% -44%
no_tmp 1117/s 79% 60% 33% -- -26%
base 1510/s 142% 116% 80% 35% --
Таким образом, они отличаются, и, видимо, декларация расходов цикла. Но версии tmp
находятся в списке. Кроме того, это часто просто накладные расходы, поэтому он сильно преувеличен. И есть и другие аспекты: – no_tmp
работает в одном из утверждений, например. Эти вещи могут иметь значение только в том случае, если ваша обработка является главным образом итерациями. Просто генерировать (высокое качество) псевдослучайное число дорого.
Это может также отличаться (дико) на разных версиях аппаратного и программного обеспечения. Мои результаты с v5.10 на более качественной машине немного разные. Замените образец «расчеты» на вашу обработку и запустите на самом аппаратном обеспечении для соответствующей меры, независимо от того, имеет ли это значение вообще.
Просто для полноты: я попробовал свой код и добавил измененную версию 'no_tmp()', которая также выполняет умножение (как и остальные), т. Е. Вместо вашего '$ x + = $ _;' Я сделал '$ x = 2 * $ _ + $ _; ', так что все подпрограммы дают тот же результат. Из-за умножения мой 'no_tmp_mod()' медленнее вашего и ближе к 'tmp_out()'. [См. Hastebin] (http://hastebin.com/hubewisehi.pl). Но, как вы уже сказали, реальная разница будет получена от фактического расчета, а не от _in_ vs. _out_. – PerlDuck
@PerlDog Да, это другое, спасибо за комментарий. Я хотел добавить добавление «ссылки», которое не то же самое, но я должен добавить больше, вы правы. Кроме того, есть проблемы с оптимизацией '$ tmp' и т. Д. Это должно было быть базовым образцом для OP и простой демонстрацией. Я планирую улучшить, поскольку получаю немного времени. Спасибо – zdim
@PerlDog Наконец-то обошел его и обновил, как и планировалось. Спасибо за комментарий! – zdim