Differenza prestazionale tra argomento stdin e riga comandi


11

Per alcuni comandi, è possibile specificare determinati input come argomento stdin o riga di comando.

Specificamente, supponiamo commandpuò prendere l'input stdin e un nome di file come argomento della riga di comando, e command < myfile, cat myfile | command e command myfilepuò produrre lo stesso risultato.

Per esempio,

Quando il comando è sed:

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

Quando il comando è cat:

cat < myfile
cat myfile
  1. Mi chiedevo se ci fossero delle regole generali sulle loro esibizioni, cioè quale di esse è di solito la più efficiente e quale la meno?
  2. Il reindirizzamento è sempre meglio di pipe?

1
Vorrei che tutti facessero queste domande (duplicate) e scrivessero da sole il loro guscio come esercizio.
alex

1
per favore non usare "Grazie!" nelle tue domande. Vota le risposte per esprimere la tua gratitudine.
alex

@Alex: se si tratta di un duplicato, si prega di collegarsi al duplicato e lavoreremo per chiuderlo. In genere ti asterrai dal rispondere a una domanda che sai essere un duplicato e segnalarla per l'attenzione del moderatore.
Caleb,

1
@alex: dove posso imparare a scrivere la mia shell?
Tim

@Caleb: sono sicuro che questo è stato chiesto 2 o 3 volte nell'ultimo mese, ma non ho il link a portata di mano :-p
alex

Risposte:


6

La cat file | commandsintassi è considerata un uso inutile diCat . Di tutte le opzioni, ci vuole un impatto sulle prestazioni perché deve generare un altro processo nel kernel. Per quanto insignificante questo possa rivelarsi nel quadro generale, è sovraccarico le altre forme non hanno. Questo è stato trattato su domande come: dovrei preoccuparmi dei gatti non necessari?

Tra le altre due forme non ci sono praticamente differenze di prestazioni. STDIN è un nodo file speciale che il processo deve aprire e leggere come qualsiasi altro. Passare un nome file invece di STDIN fa semplicemente aprire un altro file.

La differenza sarebbe in quali caratteristiche / flessibilità stai cercando.

  • Passare il nome del file al programma significherebbe che il file di input era ricercabile. Questo può o meno avere importanza per il programma, ma alcune operazioni possono essere accelerate se il flusso è ricercabile.
  • Conoscere il file di input effettivo consente al programma di scrivere potenzialmente su di esso. Ad esempio sed -iper la modifica sul posto. (Nota: poiché questo deve creare un nuovo file dietro le quinte non è un guadagno in termini di prestazioni rispetto ad altri reindirizzamenti, ma è un passaggio pratico.)
  • L'uso dei reindirizzamenti della shell consente di concatenare più file o persino di utilizzare il reindirizzamento dei processi. sed [exp] < file1 file2o anche sed [exp] < <(grep command). I dettagli di questo caso d'uso sono disponibili su questa domanda: sostituzione del processo e pipe

La sostituzione del processo dovrebbe funzionare senza la necessità di convogliare il risultato; sed [exp] < <(grep command)funzionerà perfettamente come sed [exp] <(grep command)(poiché <(grep command)crea un file temporaneo denominato per la lunghezza del comando che sedè perfettamente in grado di aprirsi da solo senza l'assistenza della shell).
ShadowRanger,

2
  1. Dato che command fileapre il file e da quel momento in poi funziona come se lo fosse stdin, c'è poca differenza. Con il reindirizzamento della shell è sufficiente aprire prima il file (shell does,) invece del comando binario stesso.

  2. Se stiamo parlando di cat file | commandvs. command <file, allora è preferibile quest'ultima. Non noterai differenze significative nelle prestazioni tra i due, ma il primo è inutilmente complicato (processo extra e buffer di memoria condivisa per la pipe, con throughput limitato). Inoltre, non puoi seek(cambiare arbitrariamente la posizione del puntatore del file) in un pipe, mentre è possibile in un file ordinario. Alcuni comandi potrebbero utilizzare un algoritmo più efficiente quando seekè possibile -ing nel file di input.


Direi che il file di comando è preferito rispetto al comando <file, perché il comando potrebbe eseguire una sorta di accesso non sequenziale.
user606723

E cosa gli impedirebbe di farlo <file? Il tuo punto è valido per usare il nome del file di input per derivare il nome del file di output, ad esempio: gzip fileproduce file.gz.
alex

forse non capisco come il reindirizzamento funzioni internamente. Diciamo che reindirizziamo un film da 12 GB in mplayer / vlc, e poi saltiamo alla fine. Cosa succederebbe esattamente in questo caso?
user606723

1
Shell apre il file e crea un processo secondario, che eredita il descrittore di file. Il processo biforcuta closes stdine le chiamate dupsul descrittore di file aperto, in modo da sostituire il vecchio stdin(che era una sorta di tty nella maggior parte dei casi). Dal punto di giocatore di film di vista non c'è alcuna differenza tra questo e aprendo il file dal suo nome nel giocatore stesso. Il descrittore di file è ricercabile in entrambi gli scenari, quindi quando saltiamo alla fine non c'è alcuna differenza rilevabile dall'utente.
alex
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.