8

I have a Java-program which communicates with a C++ program using a socket on localhost. Can I expect to gain any performance (either latency, bandwidth, or both) by moving to use a native OS pipe? I'm primarily interested in Windows at the moment, but any insight related to Unix/Linux/OSX is welcome as well.

EDIT: Clarification: both programs run on the same host, currently communicating via a socket, i.e. by making a TCP/IP connection to localhost:. My question was what are the potential performance benefits of switching to using (local) named pipes (Windows), or their Unix equivalent (AF_UNIX domain socket?).

JesperE
  • 63,317
  • 21
  • 138
  • 197
  • If IPC is really a bottleneck, how about using JNI and running it in the same process? A function call is probably faster than any IPC. – Ken Dec 11 '09 at 21:22
  • There are several reasons. JVM stability is probably the most important. The external code needs to be able to load 3rd-party DLLs of varying quality, and I do not want these to be able to take down the JVM when they crash. Not having to build and link against JVM libraries is also a big win. – JesperE Dec 12 '09 at 08:44
  • Looking at the protocols, as I've been doing this week, there is no way that named pipes are faster than TCP sockets. Every named pipe read involves sending a read request to the peer. TCP doesn't have that. Data is all buffered at one end so there is no windowing. TCP tries to fill the pipe and has windowing. – user207421 Jun 12 '23 at 07:37

3 Answers3

10

Ken is right. Named pipes are definitely faster on Windows. On UNIX & Linux, you'd want a UDS or local pipe. Same thing, different name.

Anything other than sockets will be faster for local communication. This includes memory mapped files, local pipes, shared memory, COM, etc.

pestilence669
  • 5,698
  • 1
  • 23
  • 35
  • 1
    I'm pretty sure a Unix Domain Socket is different from a named pipe (which do exist on Linux and probably every modern UNIX). – Ken Dec 10 '09 at 19:43
  • Oh, just realized you might have meant that either is acceptable, and only "local pipe" is a synonym for "named pipe". I've never heard that (this page is now #3 on google for "linux local pipe"!). – Ken Dec 10 '09 at 19:45
  • Yeah, I wasn't very clear. I steered clear of mentioning Apple's named "socket," but still managed to make it confusing. :) – pestilence669 Dec 10 '09 at 22:36
  • 1
    Thanks. You don't happen to have (or know) or any benchmarks? – JesperE Dec 11 '09 at 17:43
  • BTW: what about latency vs. bandwidth. The communication pattern is usually lots of small messages sent back and forth, so low latency is probably more important than high bandwidth. – JesperE Dec 11 '09 at 17:44
  • Named pipes & UDSs have less latency, more bandwidth and less CPU overhead than a TCP socket... pretty much always. If you're really wanting the fastest *Windows* IPC, however, memory mapped files reign supreme. – pestilence669 Dec 11 '09 at 23:09
  • By bandwidth I think you mean throughput. – Leeks and Leaks Jan 31 '10 at 02:01
  • @leeks-and-leaks Correct. I might was probably inebriated when I typed this out – pestilence669 Jan 31 '10 at 04:40
  • Hard to believe. In named pipes every read and every write is preceded by a read or write *request* packet, which can only add latency. That's why `TransactNamedPipe()` exists. Furthermore there is no windowing and no attempt to fill the pipe. – user207421 Jun 12 '23 at 10:39
1

The first google hit turned up this, which clocked NT4 and XP and found named pipes (that's what you meant, right?) to be faster on Windows.

Ken
  • 1,066
  • 1
  • 10
  • 17
  • 1
    I'm confused. The numbers on the page seem to indicate that named pipes are **slower** compared to socket, but maybe I'm reading the numbers wrong. – JesperE Dec 11 '09 at 17:42
  • @JesperE check again, sthe specs of the machines that did the socket tests outclass the machines for the pipe test by more than 10:1 and on the pipe test rigs the nic is being maxed out, so taking that into account the pipes are certainy faster. (but thats a really bad way to benchmark imo) – Lawrence Ward Aug 11 '13 at 22:30
  • 1
    This benchmark is designed in a really weird way: the author takes two pairs of computers from completely different generations, with different network technologies and tests each technology on *one pair of machines* only. He then guesstimates what the disparity should have been if the technologies had the same performance characteristics. He also does not seem to be bothered by the fact that one of the results he got is two orders of magnitude higher than the theoretical limit for the network technology in question. I would not base any conclusions on that page. – EFraim Nov 15 '15 at 09:15
0

For local processes communication pipes are definitely faster than sockets. Here is a benchmark or cached here.

SYSV IPC vs. UNIX pipes vs. UNIX sockets

Latency test

Samples: 1 million

Method Average latency (us)

SYSV IPC msgsnd/rcv 7.0

UNIX pipe 5.9

UNIX sockets 11.4

Bandwidth test

Samples: 1 million

Data size: 1 kB

Block size: 1 kB

Method Average bandwidth (MB/s)

SYSV IPC msgsnd/rcv 108

UNIX pipe 142

UNIX sockets 95

Notes

msgsnd/rcv have a maximum block size: on my system it’s about 4kB. Performance increases as block size is raised towards the ceiling. The highest bandwidth I could achieve was 284 MB/s, with a block size of 4000 bytes and a data size of 2MB. Performance dropped off slightly as the data size was decreased, with 4kB of data giving a bandwidth of 266 MB/s.

I don’t know what block size my system uses internally when transferring data through a pipe, but it seems a lot higher than 4kB. Using a block size of 32kB, I could achieve over 500 MB/s. I tested this with various data sizes from 32kB to 32MB and each time achieved 400-550 MB/s. Performance tailed off as the data and block sizes were decreased, similarly as the block size was raised.

Unix socket performance is much better with a higher block size than 1kB. I got best results (134 MB/s) with 2kB blocks, 4kB data size. This is comparable with UNIX pipes.

I’m not sure if my testing methods are perfect. Bandwidth testing seems fairly straightforward, but I kind of guessed at how to test latency. I just sent 1 character back and forth between two processes living at either end of a fork().

One factor I didn’t test is the time taken to bind() a UNIX socket and connect() to the server. If you keep connections open, it’s obviously not significant.

Conclusion

On my system, UNIX pipes give higher bandwidth and lower latency than SYSV IPC msgsnd/rcv and UNIX sockets, but the advantage depends on the block size used. If you are sending small amounts of data, you probably don’t need to worry about speed, just pick the implementation that suits you. If you want to shift a huge amount of data, use pipes with a 32kB block size.

System information

CPU : Intel Celeron III (Coppermine)

RAM : 256MB

Kernel : Linux 2.2.18

I think even though socket is flexible but it can also lead to bad code design. While using pipe it enforces you to design the architecture of your project like which process should be the parent which should be the children and how they cooperate(this will determine how pipes are established) and assign different functionality to processes. Your project design this way will have hierarchical structure and easy to maintain.

https://web.archive.org/web/20160401124744/https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets

shuyan
  • 99
  • 1
  • 6
  • Link gives error 404 not found. In any case the relevant parts of it should have been quoted here, with citation. – user207421 Jun 12 '23 at 08:11