Sì, rallenta le cose. E fondamentalmente ha una coda di dati non scritti, sebbene sia effettivamente gestita dal kernel - tutti i programmi lo hanno, a meno che non richiedano esplicitamente diversamente.
Ad esempio, ecco una banale pipe che utilizza pv
, il che è carino perché mostra la velocità di trasferimento:
$ pv -s 50g -S -pteba /dev/zero | cat > /dev/null
50GiB 0:00:09 [ 5.4GiB/s] [===============================================>] 100%
Ora aggiungiamo un file tee
lì dentro, nemmeno scrivendone una copia aggiuntiva, ma solo inoltrandolo:
$ pv -s 50g -S -pteba /dev/zero | tee | cat > /dev/null
50GiB 0:00:20 [2.44GiB/s] [===============================================>] 100%
Quindi, è un po 'più lento e non stava nemmeno facendo nulla! Questo è il sovraccarico del tee che copia internamente STDIN in STDOUT. (È interessante notare che l'aggiunta di un secondo pv
rimane a 5.19GiB / s, quindi pv
è sostanzialmente più veloce di tee
. pv
Usi splice(2)
, tee
probabilmente no.)
Comunque, vediamo cosa succede se dico tee
di scrivere su un file su disco. Inizia abbastanza velocemente (~ 800 MiB / s) ma man mano che procede, continua a rallentare, fino a raggiungere ~ 100 MiB / s, che è sostanzialmente il 100% della larghezza di banda di scrittura del disco. (L'avvio rapido è dovuto al fatto che il kernel memorizza nella cache la scrittura del disco e il rallentamento della velocità di scrittura del disco è il rifiuto del kernel di far crescere la cache all'infinito.)
Importa?
Quanto sopra è il caso peggiore. Quanto sopra utilizza una pipe per diffondere i dati il più velocemente possibile. L'unico uso del mondo reale che mi viene in mente in questo modo è il piping di dati YUV grezzi da / a ffmpeg
.
Quando invii dati a velocità inferiori (perché li stai elaborando, ecc.) Avrà un effetto molto meno significativo.