Нужны экспертные предложения по сравнению ниже:
Сегмент кода с использованием цикла:
for file in `cat large_file_list`
do
gzip -d $file
done
Сегмент кода с использованием простого расширения:
gzip -d `cat large_file_list`
Какой из них будет быстрее? Приходится манипулировать большим набором данных.
linux
bash
shell-script
shell
Леон
источник
источник
gzip
в вашей системе, количества файлов в списке файлов и размера этих файлов.xargs gzip -d < large_file_list
tr \\n \\0 large_file_list | xargs -0 gzip -d
Ответы:
осложнения
Следующее будет работать только иногда:
Три проблемы (в
bash
большинстве других оболочек типа Борна):Он потерпит неудачу, если в любом имени файла есть пробел или символы новой строки (при условии, что
$IFS
он не был изменен). Это из-за разбиения слов в оболочке .Также может произойти сбой, если в имени любого файла есть глобальные активные символы. Это связано с тем, что оболочка будет применять расширение пути к списку файлов.
Также произойдет сбой, если имена файлов начинаются с
-
(еслиPOSIXLY_CORRECT=1
это относится только к первому файлу) или если какое-либо имя файла есть-
.Также произойдет сбой, если в нем слишком много имен файлов, чтобы поместиться в одной командной строке.
Код ниже подвержен тем же проблемам, что и код выше (кроме четвертого)
Надежное решение
Если у вас
large_file_list
есть ровно одно имя файла в строке, и названный файл-
не входит в их число, и вы работаете в системе GNU, тогда используйте:-d'\n'
говорит, чтоxargs
нужно обрабатывать каждую строку ввода как отдельное имя файла.-r
говоритxargs
не запускать команду, если входной файл пуст.--
говорит,gzip
что следующие аргументы не должны рассматриваться как параметры, даже если они начинаются с-
.-
один будет по-прежнему рассматриваться как-
вместо файла, который называется-
.xargs
поместит много имен файлов в каждой командной строке, но не так много, чтобы оно превысило предел командной строки. Это уменьшает количество раз, котороеgzip
процесс должен быть запущен и, следовательно, делает это быстро. Это также безопасно: имена файлов также будут защищены от разделения слов и расширения пути .источник
for
Цикл будет, безусловно, самым медленным. Два других метода будут очень близки по скорости друг к другу.xargs
: по крайней мере, в версии GNU есть--arg-file
опция (краткая форма-a
). Так что можно сделатьxargs -a large_file_list -rd'\n' gzip -d
вместо этого. Фактически, нет никакой разницы, кроме того факта, что он<
является оператором оболочки и будетxargs
выполнять чтение из stdin (который оболочка «связывает» с файлом), в то время как он-a
будетxargs
явно открывать рассматриваемый файлparallel
для запуска нескольких копийgzip
, ноxargs
(по крайней мере, один GNU), также имеет-P
переключатель для этого. На многоядерных машинах это может иметь значение. Но также возможно, что декомпрессия полностью связана с вводом / выводом.Я сомневаюсь, что это будет иметь большое значение.
Я бы использовал цикл только потому, что я не знаю, сколько файлов указано в списке файлов, и я не знаю (обычно), есть ли в именах файлов пробелы. Выполнение подстановки команды, которая генерирует очень длинный список аргументов, может привести к ошибке «Список аргументов слишком длинный», когда длина генерируемого списка слишком велика.
Моя петля будет выглядеть так
Это дополнительно позволило бы мне вставить команды для обработки данных после
gunzip
команды. Фактически, в зависимости от того, что на самом деле представляют собой данные и что нужно с ними делать, может быть даже возможно обработать их, не сохраняя их вообще в файл:(где
process_data
какой-то конвейер, который читает несжатые данные из стандартного ввода)Если обработка данных занимает больше времени, чем распаковка, вопрос о том, является ли цикл более эффективным или нет, становится неактуальным.
В идеале , я бы предпочел не работать со списком имен файлов, а вместо этого использовать шаблон выделения имени файла, как в
где
./*.gz
образец, соответствующий соответствующим файлам. Таким образом, мы не зависим от количества файлов или символов, используемых в именах файлов (они могут содержать символы новой строки или другие пробельные символы, или начинаться с тире и т. Д.)Связанные с:
источник
Из этих двух тот, у которого все файлы передаются за один вызов,
gzip
скорее всего будет быстрее, потому что вам нужно запуститьgzip
только один раз. (То есть, если команда работает вообще, см. Другие ответы для предостережений.)Но я хотел бы напомнить о золотом правиле оптимизации : не делайте это преждевременно.
Не оптимизируйте подобные вещи, пока не узнаете, что это проблема.
Эта часть программы занимает много времени? Что ж, распаковка больших файлов может, и вам все равно придется это делать, так что на этот вопрос будет нелегко ответить.
Мера. На самом деле, это лучший способ быть уверенным.
Вы увидите результаты своими глазами (или с вашим собственным секундомером), и они будут применяться к вашей ситуации, чего не могут быть случайные ответы в Интернете. Поместите оба варианта в скрипты и запустите
time script1.sh
, иtime script2.sh
. (Сделайте это со списком пустых сжатых файлов, чтобы измерить абсолютную величину накладных расходов.)источник
Как быстро ваш диск?
Это должно использовать все ваши процессоры:
Таким образом, ваш предел, вероятно, будет скорость вашего диска.
Вы можете попробовать настроить с помощью
-j
:Это будет запускать половину заданий параллельно с предыдущей командой и меньше нагружать ваш диск, поэтому в зависимости от вашего диска это может быть быстрее.
источник