I'm trying to understand how named pipes work so that I can streamline my one-way interprocess communication. I expect some overhead due to copying data into a circular buffer, which I would have thought is stored in RAM, and so I expected the pipe to be much faster than writing to a file (because RAM is orders of magnitude faster than disk).
Instead, I found that the named pipe (or anonymous pipe) is about the same speed as a file. This is on a 3 GHz desktop with an ordinary disk drive (not solid state), running Ubuntu Linux. Here's a simplified test program in 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)))
Piping straight to /dev/null
:
python test.py > /dev/null
yields 2.1 microseconds (constant) for each megabyte.
Piping to a file:
python test.py > /tmp/testout.txt
jumps between 500 microseconds and 930 microseconds (the larger value gets more common as the file gets larger--- presumably, it's looking for disk space).
Then the named pipe:
mkfifo testpipe
cat testpipe > /dev/null &
python test.py > testpipe
yields 640 microseconds (constant) and an unnamed pipe:
python test.py | cat > /dev/null
also yields 650 microseconds (constant).
Can anyone explain why the pipe's speed is more like the file's speed than /dev/null
's speed? Might I have a switch somewhere that says, "run pipes through a file-based buffer, rather than a RAM-based buffer," and can I change that switch? Might it be a kernel option or a shell variable?
Another interpretation: suppose that the disk output jumps between 500 and 930 microseconds because the 500 is just piping and the 930 is actually writing. Then the 500 ~ 640 for piping in both cases is equivalent. However, under that interpretation, why is there only a factor of two between piping and actually writing to disk? Websites that talk about RAM disks say that RAM disks are 50-200 times faster than hard disks.
/dev/null
is actually quite cheap, while writing anywhere else - be it a file, a FIFO, a pipe or whatever - is much more expensive as it needs "a lot" of handling effort.