¿El tee ralentiza las tuberías?

10

Me pregunto si el tee ralentiza las tuberías. Escribir datos en el disco es más lento que canalizarlos, después de todo.

¿Espera tee con el envío de datos a la siguiente tubería hasta que se haya escrito en el disco? (Si no, supongo que tee tiene que poner en cola los datos que se han enviado, pero que no se han escrito en el disco, lo que me parece poco probable).

$ program1 input.txt | tee intermediate-file.txt | program2 ...
El gato no divertido
fuente
No, ese "próximo canal" es lo primero que escribe (también mencionado aquí ).
ManRow

Respuestas:

12

Sí, ralentiza las cosas. Básicamente, tiene una cola de datos no escritos, aunque en realidad el núcleo lo mantiene: todos los programas tienen eso, a menos que explícitamente soliciten lo contrario.

Por ejemplo, aquí hay una tubería trivial que usa pv, lo cual es bueno porque muestra la velocidad de transferencia:

$ pv -s 50g -S -pteba /dev/zero | cat > /dev/null 
  50GiB 0:00:09 [ 5.4GiB/s] [===============================================>] 100%

Ahora, agreguemos una teeallí, sin siquiera escribir una copia adicional, solo reenviando:

$ pv -s 50g -S -pteba /dev/zero | tee | cat > /dev/null 
  50GiB 0:00:20 [2.44GiB/s] [===============================================>] 100%            

Entonces, eso es un poco más lento, ¡y ni siquiera estaba haciendo nada! Esa es la sobrecarga de copiar internamente STDIN a STDOUT. (Curiosamente, agregar un segundo pvallí permanece en 5.19GiB / s, por lo que pves sustancialmente más rápido que tee. pvUsos splice(2), teeprobablemente no).

De todos modos, veamos qué sucede si le digo teeque escriba en un archivo en el disco. Comienza bastante rápido (~ 800MiB / s) pero a medida que avanza, se ralentiza, en última instancia, hasta ~ 100MiB / s, que es básicamente el 100% del ancho de banda de escritura del disco. (El inicio rápido se debe a que el núcleo almacena en caché la escritura del disco, y la ralentización de la velocidad de escritura del disco es que el núcleo se niega a permitir que el caché crezca infinitamente).

¿Importa?

Lo anterior es el peor de los casos. Lo anterior usa una tubería para arrojar datos lo más rápido posible. El único uso en el mundo real que se me ocurre es canalizar datos YUV sin procesar hacia / desde ffmpeg.

Cuando envía datos a velocidades más lentas (porque los está procesando, etc.) será un efecto mucho menos significativo.

derobert
fuente
Buena explicación
shubham
5

Nada sorprendente aquí, después de todo

> POSIX dice :

DESCRIPCIÓN

La utilidad tee copiará la entrada estándar a la salida estándar, haciendo una copia en cero o más archivos. La camiseta de utilidad no se buffer de salida.

Y tambien que

RAZÓN FUNDAMENTAL

El requisito de almacenamiento en búfer significa que no se permite que tee use el estándar ISO C con escrituras completamente almacenadas en buffer o en línea. No significa que tee tenga que hacer lecturas de 1 byte seguidas de escrituras de 1 byte.

Entonces, sin explicar "justificación", teeprobablemente solo leerá y escribirá hasta cuantos bytes puedan caber en su buffer de tubería a la vez, vaciando la salida en cada escritura.

Y sí, dependiendo de la aplicación, esto puede ser bastante ineficiente, así que siéntase libre de simplemente eliminar / comentar cualquiera de estos:
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L208
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L224

ManRow
fuente
+1 para los enlaces al código fuente responsable. ¿Son realmente esas partes las únicas responsables de este comportamiento, de modo que eliminarlas o comentarlas se teeejecute más rápido?
Hashim
1
¡Parece que ese sería el caso! Tee anula el esquema de almacenamiento en búfer que el sistema operativo elige de otra manera
ManRow