Recently I've been working on some extensions to ASEXOR, adding there direct support for messaging via WebSocket and I use JSON for small messages that travels between client (browser or standalone) and backend. Messages looks like these:
messages = [
{'call_id': 1, 'kwargs': {}, 'args': ['sleep', 0.1]},
{'call_id': 1, 't': 'r', 'returned': 'd53b2823d35b471282ab5c8b6c2e4685'},
{'call_id': 2, 'kwargs': {'utc': True}, 'args': ['date', '%d-%m-%Y %H:%M %Z']},
{'call_id': 2, 't': 'r', 'returned': '77da239342e240a0a3078d50019a20a0'},
{'call_id': 1, 'data': {'status': 'started', 'task_id': 'd53b2823d35b471282ab5c8b6c2e4685'}, 't': 'm'},
{'call_id': 2, 'data': {'status': 'started', 'task_id': '77da239342e240a0a3078d50019a20a0'}, 't': 'm'},
{'call_id': 1, 'data': {'status': 'success', 'task_id': 'd53b2823d35b471282ab5c8b6c2e4685', 'result': None, 'duration': 0.12562298774719238}, 't': 'm'},
{'call_id': 2, 'data': {'status': 'success', 'task_id': '77da239342e240a0a3078d50019a20a0', 'result': '27-02-2017 11:46 UTC', 'duration': 0.04673957824707031}, 't': 'm'}
]
I wondered, if choosing different serialization format(s) (similar to JSON, but binary) could bring more efficiency into the application - considering both message size and encoding/decoding processing time. I run small tests in python 3.5 (CPython and PyPy) (see tests here on gist) with few established serializers, which can be used as quick replacement for JSON and below are results (updated Dec 2nd 2017 thanks to comment below, as situation changed a bit with new libraries versions):
| Format | Total messages size (bytes) | Processing time 10000 x encoding/decoding all messages | PyPy 3 |
|---|---|---|---|
| [JSON](http://www.json.org/) (standard library) | 798 | 789 ms | 706 ms |
| JSON ([ujson](https://github.com/esnme/ultrajson)) | 798 | 181 ms | 3.14 s |
| [MessagePack](http://msgpack.org/index.html) (official lib) | 591 | 286 ms | 314 ms |
| MessagePack ([umsgpack](https://github.com/vsergeev/u-msgpack-python)) | 585 | 435 ms | 519 ms |
| [CBOR](http://cbor.io/) | 585 | 164 ms | 313 ms |
| [UBJSON](http://ubjson.org/) | 668 | 292 ms | 406 ms |
As messaging can use clients in web browser we can also look at performace of some serializers in Javascript on this page. As JSON serialization in part of browsers Web API, unsurprisingly it's fastest there.
All alternative libraries are faster then standard library JSON, some improved significatly form previous tests ( UBJSON and umsgpack). Standard library implementation of JSON serializer can be easily replaced by better performing ujson package. In PyPy interpreter standard library JSON is doing a slightly better, however every other library is performing worse, notably ujson.
Conclusions
JSON is today really ubiquitous, thanks to it's ease of use and readability. It's probably good choice for many usage scenarios and luckily JSON serializers show good performance. If size of messages is of some concern, CBOR looks like great, almost instant replacement for JSON, with similar performance in Python ( slower performance in browser is not big issues as browser will process typically only few messages) and 27% smaller messages size.
If size of messages is big concern carefully designed binary protocol ( with Protocol Buffers for instance) can provide much smaller messages ( but with additional costs in development).