Разница в производительности между stdin и аргументом командной строки

11

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

В частности, предположим, что commandв качестве аргумента командной строки можно использовать ввод stdin и имя файла command < myfile, cat myfile | command а также command myfileможет выдавать один и тот же результат.

Например,

Когда команда sed:

sed s/day/night/ <myfile >new   
sed s/day/night/ myfile >new    
cat myfile | sed s/day/night/ >new

Когда команда cat:

cat < myfile
cat myfile
  1. Мне было интересно, есть ли какие-то общие правила в отношении их исполнения, то есть, какое из них обычно наиболее эффективно, а какое наименее?
  2. Перенаправление всегда лучше, чем труба?
Тим
источник
1
Я желаю всем, кто задает эти (дублированные) вопросы, написать в качестве упражнения свою собственную оболочку с нуля.
Алекс
1
пожалуйста, не используйте "Спасибо!" в ваших вопросах. Голосуйте за ответы, чтобы выразить свою благодарность.
Алекс
@ Алекс: Если это обман, пожалуйста, дайте ссылку на дубликат, и мы поработаем над его закрытием. Обычно вы воздерживаетесь от ответа на вопрос, который, как вы знаете, является дубликатом, и помечаете его как модераторское внимание.
Калеб
1
@alex: Где я могу научиться писать свою собственную оболочку?
Тим
@Caleb: Я уверен, что это спрашивалось, как 2 или 3 раза в прошлом месяце, просто не иметь под рукой ссылку :-p
alex

Ответы:

6

cat file | commandСинтаксис считается Ненужное использованиеCat . Из всех ваших вариантов, он требует снижения производительности, потому что он должен порождать другой процесс в ядре. Каким бы незначительным это ни оказалось в общей картине, это накладные расходы, которых нет у других форм. Это было рассмотрено на такие вопросы, как: Должен ли я заботиться о ненужных кошек?

Между двумя другими формами практически нет различий в производительности. STDIN - это специальный файловый узел, который процесс должен открывать и читать, как и любой другой. Передача имени файла вместо STDIN просто делает его открытым другим файлом.

Разница будет в том, какие функции / гибкость вы ищете.

  • Передача имени файла в программу будет означать, что входной файл доступен для поиска. Это может иметь или не иметь значения для программы, но некоторые операции могут быть ускорены, если поток доступен для поиска.
  • Знание фактического входного файла позволяет вашей программе потенциально писать в него. Например, sed -iдля редактирования на месте. (Примечание: поскольку для этого необходимо создать новый файл за кулисами, это не выигрыш в производительности по сравнению с другими перенаправлениями, но это удобный шаг.)
  • Использование перенаправления оболочки дает вам возможность объединить несколько файлов или даже использовать перенаправление процесса. sed [exp] < file1 file2или даже sed [exp] < <(grep command). Подробности этого варианта использования можно найти по этому вопросу: Замена процесса и канал
Калеб
источник
Подстановка процесса должна работать без необходимости передавать результаты; sed [exp] < <(grep command)будет работать так же хорошо, как sed [exp] <(grep command)(поскольку <(grep command)создает именованный временный файл для длины команды, который sedвполне может открываться самостоятельно без помощи оболочки).
ShadowRanger
2
  1. Учитывая, что command fileпросто открывает файл и с тех пор работает, как будто это было stdin, есть небольшая разница. С перенаправлением оболочки вы просто открываете файл заранее (shell делает,), а не сам бинарный файл команды.

  2. Если мы говорим о cat file | commandпротив command <file, то последний предпочтительнее. Вы не заметите значительной разницы в производительности между ними, но первая излишне сложна (дополнительный процесс и буфер общей памяти для канала, с ограниченной пропускной способностью.) Кроме того, вы не можете seek(произвольно изменить позицию указателя файла) в труба, а можно в обычном файле. Некоторые команды могут использовать более эффективный алгоритм, если seekвозможен ввод во входном файле.

Алекс
источник
Я бы сказал, что командный файл предпочтительнее команды <файл, потому что команда может делать некий последовательный доступ.
user606723
И с чем бы это мешало <file? Ваша точка зрения действительна для использования имени входного файла, чтобы получить жесткое имя выходного файла, например: gzip fileпроизводит file.gz.
Алекс
возможно я не понимаю, как перенаправление работает внутри. Допустим, мы перенаправили фильм размером 12 ГБ в mplayer / vlc, а затем перейдем к концу. Что именно произойдет в этом случае?
user606723
1
Оболочка открывает файл и разветвляет подпроцесс, который наследует дескриптор файла. Раздвоенный процесс closes stdinи вызовы dupна открытом дескрипторе файла, так что заменить старый stdin(который был своего рода TTY в большинстве случаев). С точки фильма игрока зрения нет никакой разницы между тем , что и при открытии файла по его имени в Сам игрок. Файловый дескриптор доступен для поиска в обоих сценариях, поэтому, когда мы пропускаем до конца, различий, обнаруживаемых пользователем, нет.
Алекс