Performance

python-rapidjson tries to be as performant as possible while staying compatible with the json module.

The following tables show a comparison between this module and other libraries with different data sets. Last row (“overall”) is the total time taken by all the benchmarks.

Each number show the factor between the time taken by each contender and python-rapidjson (in other words, they are normalized against a value of 1.0 for python-rapidjson): the lower the number, the speedier the contender.

In bold the winner.

Serialization

serialize dumps()[1] Encoder()[2] dumps(n)[3] Encoder(n)[4] ujson[5] simplejson[6] stdlib[7] yajl[8]
100 arrays dict 1.00 0.99 0.73 0.77 0.97 4.82 2.27 1.37
100 dicts array 1.00 1.02 0.82 0.85 0.90 5.68 2.19 1.36
256 Trues array 1.00 1.04 1.24 1.09 1.31 2.41 2.04 1.12
256 ascii array 1.00 1.01 1.04 1.09 0.49 1.01 0.95 1.08
256 doubles array 1.00 1.02 1.08 1.03 6.76 7.34 6.88 3.89
256 unicode array 1.00 0.89 0.89 0.91 0.56 0.73 0.83 0.47
complex object 1.00 1.01 0.85 0.82 1.04 4.11 2.62 2.16
composite object 1.00 1.02 0.72 0.68 0.88 2.79 1.82 1.71
overall 1.00 0.99 0.73 0.78 0.97 4.81 2.27 1.36

Deserialization

deserialize loads()[9] Decoder()[10] loads(n)[11] Decoder(n)[12] ujson simplejson stdlib yajl
100 arrays dict 1.00 1.00 0.90 0.90 0.95 1.60 1.11 1.18
100 dicts array 1.00 1.04 0.86 0.86 0.94 2.00 1.43 1.27
256 Trues array 1.00 1.16 1.10 1.12 1.20 1.95 1.90 1.89
256 ascii array 1.00 1.02 1.02 1.02 1.39 1.14 1.25 1.62
256 doubles array 1.00 0.90 0.16 0.16 0.39 0.86 0.83 0.42
256 unicode array 1.00 1.01 1.01 1.00 1.02 5.14 5.34 2.40
complex object 1.00 1.01 0.73 0.73 0.88 1.60 1.14 1.20
composite object 1.00 1.02 0.81 0.81 0.85 1.97 1.42 1.26
overall 1.00 1.00 0.90 0.90 0.95 1.61 1.12 1.18
[1]rapidjson.dumps()
[2]rapidjson.Encoder()
[3]rapidjson.dumps(number_mode=NM_NATIVE)
[4]rapidjson.Encoder(number_mode=NM_NATIVE)
[5]ujson 1.35
[6]simplejson 3.11.1
[7]Python 3.6.2 standard library json
[8]yajl 0.3.5
[9]rapidjson.loads()
[10]rapidjson.Decoder()
[11]rapidjson.loads(number_mode=NM_NATIVE)
[12]rapidjson.Decoder(number_mode=NM_NATIVE)

DIY

To run these tests yourself, clone the repo and run:

$ tox -e py36 -- -m benchmark --compare-other-engines

Without the option --compare-other-engines it will focus only on RapidJSON. This is particularly handy coupled with the compare past runs functionality of pytest-benchmark:

$ tox -e py36 -- -m benchmark --benchmark-autosave
# hack, hack, hack!
$ tox -e py36 -- -m benchmark --benchmark-compare=0001

----------------------- benchmark 'deserialize': 18 tests ------------------------
Name (time in us)                                                            Min…
----------------------------------------------------------------------------------
test_loads[rapidjson-256 Trues array] (NOW)                         5.2320 (1.0)…
test_loads[rapidjson-256 Trues array] (0001)                        5.4180 (1.04)…
…

To reproduce the tables above, use the option --benchmark-json so that the the results are written in the specified filename the run the benchmark-tables.py script giving that filename as the only argument:

$ tox -e py36 -- -m benchmark --compare-other-engines --benchmark-json=comparison.json
$ python3 benchmark-tables.py comparison.json