Ja, es verlangsamt die Dinge. Und es hat im Grunde eine Warteschlange mit ungeschriebenen Daten, obwohl diese tatsächlich vom Kernel verwaltet wird - alle Programme haben diese, sofern sie nicht ausdrücklich etwas anderes anfordern.
Hier ist zum Beispiel eine triviale Pipe mit pv
, was schön ist, weil es die Übertragungsrate anzeigt:
$ pv -s 50g -S -pteba /dev/zero | cat > /dev/null
50GiB 0:00:09 [ 5.4GiB/s] [===============================================>] 100%
Fügen wir nun eine hinzu und tee
schreiben nicht einmal eine zusätzliche Kopie - leiten Sie sie einfach weiter:
$ pv -s 50g -S -pteba /dev/zero | tee | cat > /dev/null
50GiB 0:00:20 [2.44GiB/s] [===============================================>] 100%
Das ist also etwas langsamer und es hat nicht einmal etwas getan! Das ist der Aufwand für das interne Kopieren von STDIN nach STDOUT. (Interessanterweise pv
bleibt das Hinzufügen einer Sekunde dort bei 5,19 GB / s, pv
ist also wesentlich schneller als tee
. pv
Verwendet splice(2)
, tee
wahrscheinlich nicht.)
Wie auch immer, mal sehen, was passiert, wenn ich sage tee
, dass ich in eine Datei auf der Festplatte schreiben soll. Es beginnt ziemlich schnell (~ 800 MB / s), verlangsamt sich jedoch im Laufe der Zeit immer weiter - letztendlich auf ~ 100 MB / s, was im Grunde 100% der Festplattenschreibbandbreite entspricht. (Der schnelle Start ist darauf zurückzuführen, dass der Kernel das Schreiben der Festplatte zwischenspeichert, und die Verlangsamung der Schreibgeschwindigkeit der Festplatte ist der Kernel, der sich weigert, den Cache unendlich wachsen zu lassen.)
Ist das wichtig?
Das Obige ist ein Worst-Case. Das obige verwendet eine Pipe, um Daten so schnell wie möglich auszuspucken. Die einzige reale Verwendung, die ich mir so vorstellen kann, ist das Weiterleiten von YUV-Rohdaten an / von ffmpeg
.
Wenn Sie Daten mit langsameren Raten senden (weil Sie sie verarbeiten usw.), ist dies ein viel weniger bedeutender Effekt.