Каков самый быстрый способ "распечатать" файл в perl?

Я писал вывод из скриптов perl в файлы в течение некоторого времени, используя следующий код:

open( OUTPUT, ">:utf8", $output_file ) or die "Can't write new file: $!";
print OUTPUT "First line I want printed\n";
print OUTPUT "Another line I want printing\n";
close(OUTPUT);

Это работает и быстрее, чем мой первоначальный подход, который использовал "сказать" вместо печати (спасибо NYTProf за то, что он просветил меня!)

Однако мой текущий script перебирает сотни тысяч строк и занимает много часов, чтобы запустить этот метод, а NYTProf указывает пальцем на мои тысячи команд "print". Итак, вопрос... Есть ли более быстрый способ сделать это?

Другая информация, которая, возможно, релевантна... Perl Версия: 5.14.2 (On Ubuntu)

История вопроса script... Ряд '|' разграниченные плоские файлы считываются в хеши, каждый файл имеет какие-то первичные ключи, сопоставляющие записи от одного к другому. Я манипулирую этими данными, и они объединяют их в один файл для импорта в другую систему.

Выходной файл составляет около 3 миллионов строк, и программа начинает заметно замедляться после записи около 30 000 строк в указанный файл. (Небольшое чтение, казалось, указывало на то, что вы исчерпали буфер записи на других языках, но я не мог найти ничего об этом в отношении perl?)

EDIT: Теперь я попытался добавить строку ниже, сразу после инструкции open(), чтобы отключить буферизацию печати, но программа все еще замедляется около 30 000-й строки.

OUTPUT->autoflush(1);
2 ответа

Я думаю, вам нужно перепроектировать алгоритм, который использует ваша программа. Скорость вывода файлов не зависит от объема данных, которые были выведены, и гораздо более вероятно, что ваша программа считывает и обрабатывает данные, но не освобождает их.

  • Проверьте количество памяти, используемое вашим процессом, чтобы узнать, неуклонно растет ли она

  • Остерегайтесь циклов for (<$filehandle>), которые сразу считывают целые файлы в память

  • Как я уже сказал в своем комментарии, отключите соответствующие инструкции print, чтобы увидеть, как изменения производительности


Вы пытались скомпоновать всю одиночную печать в один скаляр, а затем сразу сканировать скаляр? У меня есть script, который выводит в среднем по 20 строк текста для каждой строки ввода. При использовании отдельных операторов печати даже отправка вывода в /dev/null потребовала много времени. Но когда я собрал весь вывод (для одной строки ввода) вместе, используя такие вещи, как:

$output .= "...";

$output .= sprintf("%s...", $var);

Затем, перед тем как покинуть подпрограмму обработки строки, я напечатаю $output. Печать всех строк сразу. Количество вызовов на печать перешло от ~ 7.7M до около 386K - равно количеству строк в файле даты ввода. Это выбрит на 10% от моего общего времени выполнения.

licensed under cc by-sa 3.0 with attribution.