<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>Iíve been testing a lot of combinations of ZeroMQ over Java, between the pure jeromq base and the jzmq JNI libzmq C code. Albeit my impression so far is that jeromq is way faster than the binding - not that the code isnít great, but my feeling so far is that the JNI jump slows everything down - at a certain point I felt the need for a simple zmq_proxy network node and I was pretty sure that the C code must be faster than the jeromq. I have some ideas that can improve the jeromq proxy code, but it felt easier to just compile the zmq_proxy code from the book.</div><div><br></div><div>Unfortunately something went completely wrong on my side so I need your help to understand what is happening here.</div><div><br></div><div>Context:</div><div>MacOSX Mavericks fully updated, MBPro i7 4x2 CPU 2.2Ghz 16GB</div><div>libzmq from git head</div><div>(same for jeromq and libzmq, albeit Iím using my own fork so I can send pulls back)</div><div>my data are json lines that goes from about 100 bytes to some multi MB exceptions, but the average of those million messages is about 500bytes.</div><div><br></div><div>Test 1: pure local_thr and remote_thr:</div><div><br></div><div>iDavi:perf bruno$ ./local_thr <a href="tcp://127.0.0.1:8881">tcp://127.0.0.1:8881</a> 500 1000000 &<br>iDavi:perf bruno$ time ./remote_thr <a href="tcp://127.0.0.1:8881">tcp://127.0.0.1:8881</a> 500 1000000 &<br>real<span class="Apple-tab-span" style="white-space:pre">       </span><b>0m0.732s</b><br>user<span class="Apple-tab-span" style="white-space:pre">   </span>0m0.516s<br>sys<span class="Apple-tab-span" style="white-space:pre">       </span>0m0.394s<br>message size: 500 [B]<br>message count: 1000000<br>mean throughput: <b>1418029</b> [msg/s]<br>mean throughput: <b>5672.116</b> [Mb/s]<br><br></div><div>Test 2: change local_thr to perform connect instead of bind, and put a proxy in the middle.</div><div>The proxy is the first C code example from the book, available here <a href="https://gist.github.com/davipt/7361477">https://gist.github.com/davipt/7361477</a></div><div>iDavi:c bruno$ gcc -o proxy proxy.c -I /usr/local/include/ -L /usr/local/lib/ -lzmq</div><div>iDavi:c bruno$ ./proxy <a href="tcp://*:8881">tcp://*:8881</a> <a href="tcp://*:8882">tcp://*:8882</a> 1<br>Proxy type=PULL/PUSH in=<a href="tcp://*:8881">tcp://*:8881</a> out=<a href="tcp://*:8882">tcp://*:8882</a><br><br></div><div>iDavi:perf bruno$ ./local_thr <a href="tcp://127.0.0.1:8882">tcp://127.0.0.1:8882</a> 500 1000000 &<br>iDavi:perf bruno$ time ./remote_thr <a href="tcp://127.0.0.1:8881">tcp://127.0.0.1:8881</a> 500 1000000 &<br>iDavi:perf bruno$ message size: 500 [B]<br>message count: 1000000<br>mean throughput: <b>74764</b> [msg/s]<br>mean throughput: <b>299.056</b> [Mb/s]<br><br>real<span class="Apple-tab-span" style="white-space:pre">        </span><b>0m10.358s</b><br>user<span class="Apple-tab-span" style="white-space:pre">  </span>0m0.668s<br>sys<span class="Apple-tab-span" style="white-space:pre">       </span>0m0.508s<br><br></div><div><br></div><div>Test3: use the jeromq equivalent of the proxy: <a href="https://gist.github.com/davipt/7361623">https://gist.github.com/davipt/7361623</a></div><div><br></div><div>iDavi:perf bruno$ ./local_thr <a href="tcp://127.0.0.1:8882">tcp://127.0.0.1:8882</a> 500 1000000 &<br>[1] 15816<br>iDavi:perf bruno$ time ./remote_thr <a href="tcp://127.0.0.1:8881">tcp://127.0.0.1:8881</a> 500 1000000 &<br>[2] 15830<br>iDavi:perf bruno$ <br>real<span class="Apple-tab-span" style="white-space:pre">    </span><b>0m3.429s</b><br>user<span class="Apple-tab-span" style="white-space:pre">   </span>0m0.654s<br>sys<span class="Apple-tab-span" style="white-space:pre">       </span>0m0.509s<br>message size: 500 [B]<br>message count: 1000000<br>mean throughput: <b>293532</b> [msg/s]<br>mean throughput: <b>1174.128</b> [Mb/s]<br><br></div><div>This performance coming out of Java is okish, itís here just for comparison, and Iíll spend some time looking at it.</div><div><br></div><div>The core question is the C proxy - why 10 times slower than the no-proxy version?</div><div><br></div><div>One thing I noticed, by coincidence, is that on the upper side of the proxy, both with the C ďproducerĒ as well as the java one, tcpdump shows me consistently packets of 16332 (or the MTU size if using ethernet, 1438 I think). This value is consistent for the 4 combinations of producers and proxies (jeromq vs c).</div><div><br></div><div>But on the other side of the proxy, the result is completely different. With the jeromq proxy, I see packets of 8192 bytes, but with the C code I see packets of either 509 or 1010. It feels like the proxy is sending the messages one by one. Again, this value is consistent with the PULL consumer after the proxy, being it C or java.</div><div><br></div><div>So this is something on the proxy ďbackendĒ socket side of the zmq_proxy.</div><div><br></div><div>Also, I see quite similar behavior with a PUB - [XSUB+Proxy+XPUB] - SUB version.</div><div><br></div><div>What do I need to tweak on the proxy.c ?</div><div><br></div><div>Thanks in advance</div><div><br></div></body></html>