I am currently doing a latency benchmark of some communication middlewares and I found that ZeroMQ REQ
and REP
sockets are surprisingly slow. For example I was expecting that ZeroMQ would be faster than ZeroC Ice. For completeness here are the results of the tests so far:
- Ice 7600 messages per second
- ZeroMQ 4300 - 4500 messages per second
The message is a remote invocation with a data structure as a parameter. The data structure contains fields of basic types (int, float, double, boolean, string). At first I suspected that serializing the data with Protocol Buffers could be a bottleneck for ZeroMQ, but then I tested using empty messages and the results are fairly similar. Ice is faster even if ZeroMQ is sending empty messages.
Nevertheless I want to give ZeroMQ a fair chance. In that spirit I want to know if I can improve the speed of REQ
and REP
in any way. Maybe I should use other sockets? The only restriction is that the communication should be RPC-like. The client shouldn't do any work while it expects the result of its message.
Here is the code of my implementation. I provide the Java version of the benchmark, but the results are fairly similar for Python(a bit slower) and C++ (a bit faster):
Client
...
MQ.Context context = ZMQ.context(1);
ZMQ.Socket socket = context.socket(ZMQ.REQ);
socket.connect("tcp://*:5555");
for(int i=0; i<measuredIterations; i++){
t0 = System.nanoTime();
socket.send("",0);
socket.recv(0);
rtt = System.nanoTime() - t0;
...
}
Server
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket socket = context.socket(ZMQ.REP);
socket.bind("tcp://*:5555");
while (!Thread.currentThread().isInterrupted()){
socket.recv(0);
socket.send("",0);
}
The rest of the code is basically for calculating the average latency and the messages per second.
Maybe ZeroMQ is just slow for this communication pattern and it excels in many-to-many communication patterns...
Note: I "warmed" both middlewares before recording the results. Nevertheless ZeroMQ is always slower than Ice.
EDIT1: I increased the number of warming iterations to 10000. The new results are:
- Ice 8100 messages per second (converges to 8250 with more warming)
- ZeroMQ + Protocol Buffers converges to 4650 messsages per second