Caution: This document refers to an oldversion of ØMQ. From version 0.3.1 onwards Python extension is integral part of ØMQ and thus it doesn't have to be downloaded and built separately! Also note that Python API have changed since!
Table of Contents
|
Introduction
This whitepaper describes first version of the Python extension for ØMQ. It is simplified version of ØMQ interface exposed in the form of Python module. The python module is not yet part of ØMQ package. You have to download it separately (see below) and build it by hand. Any feedback on the Python module extension is welcome on ØMQ developer's mailing list.
Download
Download Python extension for ØMQ here.
Building it
Download and build ØMQ package:
$ tar -xzf zmq-0.3.tar.gz
$ cd zmq-0.3
$ ./configure
$ make
$ sudo make install
Download un unpack Python extension for ØMQ:
$ tar -xzf pyzmq.tar.gz
$ cd pyzmq
Compile pyzmq module:
$ python setup.py build
$ sudo python setup.py install
Using it
Python module's API is currently much simpler when compared to original C++ API. The difference is that Python module doesn't allow for full control of ØMQ threading as C++ does. Instead, the Python module extension creates single I/O thread that can be accessed from a single application thread. This doesn't allow for seamless scaling on multicore boxes. However, it is our intent to expose full ØMQ API via Python in the future.
To instantiate ØMQ:
import pyzmq
zmq = pyzmq.ZMQ (hostname)
Where hostname is name or IP address of the box where zmq_server is running.
To create wiring, create_exchange, create_queue and bind functions can be used. For detailed description of how wiring mechanism works have a look here.
eid = zmq.create_exchange ("E", pyzmq.SCOPE_GLOBAL, "10.0.0.1:5555")
zmq.create_queue ("Q", pyzmq.SCOPE_LOCAL)
zmq.bind ("E", "Q")
Sending a message is pretty straightforward.:
zmq.send (eid, msg)
Receiving a message is even simpler:
msg = zmq.receive ()
Test results
Tests were performed on two quadcore boxes (Intel Xeon CPU, E5440, 2.83 GHz) connected via direct 1Gb Ethernet link (Intel PRO/1000, PCI Express:2.5GB/s:Width x4). Operating system used was Debian Linux 4.0 (kernel version 2.6.24.7, CONFIG_PREEMPT_VOLUNTARY=y, CONFIG_PREEMPT_BKL=y, CONFIG_HZ=1000).
Latency
End-to-end latency - as measured by local_lat and remote_lat:
Message size | C++ | Python |
---|---|---|
1 B | 32.7 us | 69.8 us |
16 B | 34.54 us | 71.8 us |
256 B | 42.21 us | 86 us |
4096 B | 85.63 us | 190.8 us |
65536 B | 612.99 us | 1356.8 us |
Same values charted on the graph (black line is C++, red line is Python):
Python is rather slow when compared to C++. However, the result is expected, given that Python is a scripting engine. If the extension is used only for rapid prototyping, the slowdown is not critical anyway.
Throughput
As expected, Python is less efficient than raw C++. Until network limit (1Gb/sec) is reached the throughput is approximately 50% of the C++ throughput. However, once the messages are large enough to exhaust the network (~256 bytes) the throughputs of C++ and Python are almost exactly the same.
Message size | C++ | Python |
---|---|---|
1 B | 2,435,820 msgs/sec | 1,332,219 msgs/sec |
16 B | 2,976,623 msgs/sec | 1,340,277 msgs/sec |
256 B | 447,126 msgs/sec | 443,510 msgs/sec |
4096 B | 28,896 msgs/sec | 28,881 msgs/sec |
65536 B | 1,810 msgs/sec | 1,809 msgs/sec |
Conclusion
Python extension is measurable slower than native C++ API. However, compared to most available messaging it is still extremely fast (~70 us). Also, although it's not visible in the results, we've experienced more latency peaks with Python than with C++/C/Java APIs.
In any case, Python extension is ideal for rapid prototyping on ØMQ platform.