Эффективность Perl - Тестирование ARGV внутри цикла while (‹›)

Правильно ли я понимаю, когда заявляю следующее:

На проверку $ ARGV (т. Е. Имени файла) на предмет какого-либо условия внутри цикла while (‹>) тратятся циклы ЦП. Более эффективно сначала проверить имя файла, а затем обработать каждую строку соответственно внутри цикла while (). Таким образом, он не будет повторно проверять имя файла каждый раз, когда захватывает строку данных.

Или алмазный оператор творит чудеса, чтобы сделать это так же эффективно, как и последний?


person ansichart    schedule 25.07.2013    source источник
comment
Лучше использовать eof, чем тестировать $ARGV. См. perldoc -f eof: perldoc.perl.org/functions/eof.html.   -  person shawnhcorey    schedule 25.07.2013


Ответы (2)


Зря тратит циклы ЦП?

Вы используете Perl. Которая работает на виртуальной машине. Вы хоть представляете, сколько разыменований указателя подразумевает простой поиск глобальной переменной? Зачем вам нужны циклы? / с

Хотя оператор <> действительно подразумевает изрядное количество магии, это не оптимизирует ваши циклы. Поэтому в

my $lastfile = "";
while (<>) {
  say "file changed to ", $lastfile = $ARGV if $lastfile ne $ARGV;
  print "> $_";
}

ne проверка будет выполняться для каждой отдельной строки. Если вы оптимизируете размер кода или время разработки, это вполне приемлемо. Если вы оптимизируете общее количество выполненных кодов операций, иногда может быть дешевле открыть файлы явно:

use autodie;
for my $file (@ARGV) {
  open my $fh, "<", $file;
  say "file changed to $file";
  while (<$fh>) {
    print "> $_";
  }
}

Лично я считаю эту форму более элегантной (форма с однократным назначением), и в любом случае она не намного длиннее. Но в кратком описании я бы использовал первое решение, потому что мой сценарий мог уже запускаться тысячу раз, пока я все еще писал более длинную форму.

person amon    schedule 25.07.2013

В качестве доказательства концепции (см. Ниже) я запустил два сценария, которые я проиллюстрировал (я назвал их poc.pl и poc2.pl соответственно) в файле из одного миллиарда строк. Первый был на 21,7% медленнее. В заключение, это важно только при работе с огромным количеством строк; в этом случае язык более низкого уровня может быть лучшим выбором.

bash $  wc -l large.log
1000000000 large.log
bash $  time perl poc.pl large.log >/dev/null
  291.16s real   289.89s user     0.73s system
bash $  time perl poc2.pl large.log >/dev/null
  239.29s real   238.58s user     0.53s system
person ansichart    schedule 26.07.2013