Leistungsunterschied zwischen stdin und Befehlszeilenargument

11

Bei einigen Befehlen ist es möglich, bestimmte Eingaben entweder als stdin oder als Befehlszeilenargument anzugeben.

Insbesondere suppose commandkann nehmen stdin Eingang und einen Dateinamen als Befehlszeilenargument, und command < myfile, cat myfile | command und command myfilekann das gleiche Ergebnis erzeugen.

Beispielsweise,

Wenn der Befehl lautet sed:

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

Wenn der Befehl lautet cat:

cat < myfile
cat myfile
  1. Ich habe mich gefragt, ob es einige allgemeine Regeln für ihre Leistungen gibt, dh welche davon ist normalerweise die effizienteste und welche die am wenigsten?
  2. Ist die Umleitung immer besser als die Pipe?
Tim
quelle
1
Ich wünsche mir, dass jeder, der diese (duplizierten) Fragen stellt, als Übung seine eigene Shell von Grund auf neu schreibt.
Alex
1
Bitte benutze nicht "Danke!" in Ihren Fragen. Stimmen Sie Antworten ab, um Ihre Dankbarkeit auszudrücken.
Alex
@Alex: Wenn dies ein Betrug ist, verlinken Sie bitte auf das Duplikat und wir werden daran arbeiten, es zu schließen. Normalerweise würden Sie eine Frage, von der Sie wissen, dass sie ein Duplikat ist, nicht beantworten und sie als Aufmerksamkeit des Moderators markieren.
Caleb
1
@alex: Wo kann ich lernen, wie ich meine eigene Shell schreibe?
Tim
@Caleb: Ich bin sicher , dass dies wie 2 oder 3 Mal im letzten Monat gefragt wurde, haben einfach nicht den Link handlich :-p
alex

Antworten:

6

Die cat file | commandSyntax wird als nutzlose Verwendung von angesehenCat . Von all Ihren Optionen ist ein Leistungseinbruch erforderlich, da ein anderer Prozess im Kernel erzeugt werden muss. So unbedeutend dies auch sein mag, es ist ein Overhead, den die anderen Formen nicht haben. Dies wurde unter anderem behandelt: Sollte ich mich um unnötige Katzen kümmern?

Zwischen den beiden anderen Formen gibt es praktisch keine Leistungsunterschiede. STDIN ist ein spezieller Dateiknoten, den der Prozess wie jeder andere öffnen und lesen muss. Wenn Sie einen Dateinamen anstelle von STDIN übergeben, wird nur eine andere Datei geöffnet.

Der Unterschied besteht darin, welche Funktionen / Flexibilität Sie suchen.

  • Wenn Sie den Dateinamen an das Programm übergeben, ist die Eingabedatei durchsuchbar. Dies kann für das Programm von Bedeutung sein oder auch nicht, aber einige Vorgänge können beschleunigt werden, wenn der Stream gesucht werden kann.
  • Wenn Sie die tatsächliche Eingabedatei kennen, kann Ihr Programm möglicherweise darauf schreiben. Zum Beispiel sed -ifür die direkte Bearbeitung. (Hinweis: Da hierdurch hinter den Kulissen eine neue Datei erstellt werden muss, ist dies kein Leistungsgewinn gegenüber anderen Weiterleitungen, sondern ein praktischer Schritt.)
  • Durch die Verwendung von Shell-Weiterleitungen können Sie mehrere Dateien verketten oder sogar die Prozessumleitung verwenden. sed [exp] < file1 file2oder sogar sed [exp] < <(grep command). Details zu diesem Anwendungsfall finden Sie in dieser Frage: Prozessersetzung und Pipe
Caleb
quelle
Die Prozessersetzung sollte funktionieren, ohne dass Sie das Ergebnis weiterleiten müssen. sed [exp] < <(grep command)funktioniert einwandfrei als sed [exp] <(grep command)(da <(grep command)eine benannte temporäre Datei für die Länge des Befehls erstellt wird, die sedohne Shell-Unterstützung problemlos von selbst geöffnet werden kann).
ShadowRanger
2
  1. Angesichts der Tatsache, dass command filenur die Datei geöffnet wird und von da an so funktioniert, als ob es so wäre stdin, gibt es kaum einen Unterschied. Bei der Shell-Umleitung öffnen Sie die Datei einfach vorher (Shell tut dies), im Gegensatz zum Befehl binär selbst.

  2. Wenn wir über cat file | commandvs. sprechen command <file, wird letzteres bevorzugt. Sie werden keinen signifikanten Leistungsunterschied zwischen den beiden bemerken, aber der erstere ist unnötig kompliziert (zusätzlicher Prozess und gemeinsam genutzter Speicherpuffer für die Pipe mit begrenztem Durchsatz). Sie können auch nicht seek(die Dateizeigerposition willkürlich ändern) in a Pipe, während Sie in einer gewöhnlichen Datei können. Einige Befehle verwenden möglicherweise einen effizienteren Algorithmus, wenn seek-ing in der Eingabedatei möglich ist.

Alex
quelle
Ich würde sagen, dass die Befehlsdatei dem Befehl <file vorgezogen wird, da der Befehl möglicherweise einen nicht sequentiellen Zugriff ausführt.
user606723
Und was würde es davon abhalten <file? Ihr Punkt ist gültig für die Verwendung des Eingabedateinamens, um den Namen der Ausgabedatei abzuleiten, z . B.: gzip fileErzeugt file.gz.
Alex
Vielleicht verstehe ich nicht, wie die Umleitung intern funktioniert. Nehmen wir an, wir leiten einen 12-GB-Film in mplayer / vlc um und springen dann zum Ende. Was genau würde in diesem Fall passieren?
user606723
1
Shell öffnet die Datei und teilt einen Unterprozess auf, der den Dateideskriptor erbt. Der gegabelte Prozess closes stdinund ruft dupden geöffneten Dateideskriptor auf, sodass er den alten ersetzt stdin(was in den meisten Fällen eine Art tty war). Aus Sicht des Movie Players gibt es keinen Unterschied zwischen dem und dem Öffnen der Datei anhand ihres Namens in der Spieler selbst. Der Dateideskriptor ist in beiden Szenarien suchbar. Wenn wir also zum Ende springen, gibt es keinen vom Benutzer erkennbaren Unterschied.
Alex