Currently in pzmq there are multiple ways to implement an asynchronous IO Loop all mentioned in the documentation. http://pyzmq.readthedocs.io/en/latest/api/index.html
From a pure performance point of view, it is not clear in the documentation if the choices are equivalent. These are:
So, which one has the best throughput in messages per second in a typical PUSH-PULL scenario as shown in the documentation examples? Why do we see a difference between them?
Contrary to my expectations, it seems both asyncio implementations in pyzmq are slower than the "legacy" tornado one.
Tornado @gen.coroutine:
Avg. Speed: 2160.26 msg/s
Native @asyncio.coroutine:
Avg. Speed: 1697.66 msg/s
Tornado async:
Avg. Speed: 1695.29 msg/s
Also, the two asyncio implementations show bursts of up to 3536.27 msg/s every now and then, whereas the Tornado @gen.coroutine is very stable in throughput.
For comparing I have used modified versions of:
Tornado @gen.coroutine: https://github.com/zeromq/pyzmq/blob/master/examples/eventloop/coroutines.py
Native @asyncio.coroutine: https://github.com/zeromq/pyzmq/blob/master/examples/asyncio/coroutines.py
Tornado async: (Python 3.5+ only; included additional print coroutine) https://github.com/zeromq/pyzmq/blob/master/examples/asyncio/tornado_asyncio.py
The modification consists of displaying the number of average messages per second every 5 seconds instead of the dots. In the PULL coroutine, I increment n = n + 1
and then in the printing coroutine I calculate v = n / (time.time() - start)
and display it. Also there, I reset n = 0
and start = time.time()
every 10,000 messages to prevent any offset effects in the measurement.
$ uname -a
Linux localhost 4.6.3-300.fc24.x86_64 #1 SMP Fri Jun 24 20:52:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
$ python3 --version
Python 3.5.1
>>> zmq.__version__
'15.3.0'
>>> tornado.version
'4.3'