Estoy tratando de entender cómo funcionan las canalizaciones con nombre para poder optimizar mi comunicación unidireccional entre procesos. Espero algunos gastos generales debido a la copia de datos en un búfer circular, que habría pensado que está almacenado en la RAM, por lo que esperaba que la tubería fuera mucho más rápida que escribir en un archivo (porque la RAM es un orden de magnitud más rápido que el disco).
En cambio, descubrí que la tubería con nombre (o tubería anónima) tiene aproximadamente la misma velocidad que un archivo. Esto está en un escritorio de 3 GHz con una unidad de disco normal (no de estado sólido), ejecutando Ubuntu Linux. Aquí hay un programa de prueba simplificado en Python:
import sys
import time
import random
megabyte = "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for x in range(1024**2))
while True:
before = time.time()
sys.stdout.write(megabyte)
after = time.time()
sys.stderr.write("{} microseconds\n".format(1e6 * (after - before)))
Tubería directamente a /dev/null
:
python test.py > /dev/null
produce 2.1 microsegundos (constante) para cada megabyte.
Tubería a un archivo:
python test.py > /tmp/testout.txt
salta entre 500 microsegundos y 930 microsegundos (el valor más grande se vuelve más común a medida que el archivo se hace más grande, presumiblemente, está buscando espacio en el disco).
Entonces la tubería nombrada:
mkfifo testpipe
cat testpipe > /dev/null &
python test.py > testpipe
produce 640 microsegundos (constante) y una tubería sin nombre:
python test.py | cat > /dev/null
también produce 650 microsegundos (constante).
¿Alguien puede explicar por qué la velocidad de la tubería se parece más a la velocidad del archivo que a la velocidad del archivo /dev/null
? ¿Podría tener un conmutador en alguna parte que diga "pasar tuberías a través de un búfer basado en archivos, en lugar de un búfer basado en RAM", y puedo cambiar ese conmutador? ¿Podría ser una opción de kernel o una variable de shell?
Otra interpretación: suponga que la salida del disco salta entre 500 y 930 microsegundos porque el 500 es solo tubería y el 930 en realidad está escribiendo. Entonces el 500 ~ 640 para tuberías en ambos casos es equivalente. Sin embargo, según esa interpretación, ¿por qué solo hay un factor de dos entre la tubería y la escritura en el disco? Los sitios web que hablan sobre discos RAM dicen que los discos RAM son 50-200 veces más rápidos que los discos duros.
/dev/null
realidad es bastante barato, mientras que escribir en cualquier otro lugar, ya sea un archivo, un FIFO, una tubería o lo que sea, es mucho más costoso ya que requiere "mucho" esfuerzo de manejo.