20

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.

1
  • 1
    Writing to /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.
    – glglgl
    Dec 10, 2014 at 21:11

1 Answer 1

33

You're not seeing any performance benefit because you're not actually hitting disk when using a file - the data's on its way to the disk, but your execution thread doesn't need to wait for it to land there, so you're not actually seeing the speed penalty of hitting the disk.

If you want to wait for the disk operation to complete to see how much slower that gets, call a sync() (how to varies on your python version, see here) - you'll be looking at tens of thousands of microseconds just for your disk to seek a couple times to get the file written out (assuming it doesn't have some kind of fast write cache like in a RAID controller).

3
  • When do we get to stop worrying about the seek time of our block devices? :)
    – EEAA
    Dec 10, 2014 at 18:47
  • 5
    @EEAA All SSDs, all the time.
    – Shane Madden
    Dec 10, 2014 at 18:48
  • 1
    You're right: with a sync() the disk-write time becomes 74,000 microseconds on average. (The flush() I was doing in one variation of my test didn't do it.) So then my interpretation that the 500 ~ 640 microseconds per megabyte really is the pipe overhead makes sense, thanks. Dec 10, 2014 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.