Какой цикл for следует использовать в Perl? - PullRequest
10 голосов
/ 22 апреля 2011

Каковы аргументы для использования одного из циклов for над другим для подсчета целых чисел?

for my $i (0..$n) { ... }

for (my $i = 0; $i <= $n; $i++) { ... }

Ответы [ 5 ]

11 голосов
/ 22 апреля 2011

В вашем случае нет никакой разницы.

В других случаях использования для цикла for-each у вас нет контроля или доступа к итератору.

Используя ваш пример синтаксиса:

for my $i (0..10)
{
   print "$i";
   $i++;
}

Вышеприведенное фактически создает цикл foreach - это то же самое, что сказать foreach my $i (0..10).$i - это значение , возвращаемое из списка , а не итератор.Итератор является внутренним, и у вас нет к нему доступа;Вы не можете управлять потоком цикла.

Вывод сверху будет печатать 012345678910.

Это:

for ( my $i = 0; $i++ ; $i <= 10)
{
    print $i;
    $i++;
}

Этоэто фактический for цикл.Вы управляете и выводите итератор.Он выведет: 0246810

Кроме того:

Когда вы делаете for (1..$n), вы вызываете оператор диапазона вместо простого сравнения в верхней частипетля.Однако разница в производительности будет неизмеримой.

6 голосов
/ 22 апреля 2011

Разница между двумя стилями циклов for в Perl заключается в ясности и эффективности.

Когда вы смотрите на for my $i (0 .. $n) {...}, вы можете сразу увидеть используемый диапазон без необходимости мысленно анализировать большее выражение.

С for (my $i = 0; $i <= $n; $i++) {...} есть еще кое-что, на что можно посмотреть, и больше мест, где могут появляться ошибки.

Кроме того, foreach в диапазоне быстрее, чем эквивалентный цикл в стиле C, как показано в следующем тесте:

use Benchmark 'cmpthese';

for my $mag (map 10**$_, 1 .. 6) {
    print "\n$mag:\n";
    cmpthese -2 => {
        loop => sub {my $x = 0; for (my $i = 0; $i <= $mag; $i++) {$x += $i}},
        each => sub {my $x = 0; for my $i (0 .. $mag) {$x += $i}},
    };
}

который печатает:

10:
         Rate loop each
loop 613877/s   --  -2%
each 625568/s   2%   --

100:
         Rate loop each
loop  79481/s   -- -24%
each 104758/s  32%   --

1000:
        Rate loop each
loop  8140/s   -- -27%
each 11220/s  38%   --

10000:
       Rate loop each
loop  832/s   -- -26%
each 1124/s  35%   --

100000:
       Rate loop each
loop 81.6/s   -- -26%
each  110/s  34%   --

1000000:
       Rate loop each
loop 6.90/s   -- -26%
each 9.27/s  34%   --
5 голосов
/ 22 апреля 2011

С циклом for, состоящим из трех частей, вы можете $i += 3 и, если хотите, из цикла, но с циклом foreach это не так. В этом разница.

4 голосов
/ 22 апреля 2011

Ошибка off-by-one, которую вы изначально имели в цикле в стиле C, показывает, что цикл в стиле C более подвержен ошибкам, и его следует использовать только в том случае, если вам действительно нужен доступ к счетчику цикла.Цикл foreach значительно усложняет совершение ошибки «один за другим».

2 голосов
/ 22 апреля 2011

Я полагаю, что приведенные вами примеры двух циклов ведут себя одинаково. В обоих случаях $i имеет лексическую область (поскольку вы используете ключевое слово my). Я думаю, что синтаксис 0..$n более понятен, но (удивительно!) Не все с этим согласятся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...