Skip to content

Commit

Permalink
Benchmark against pysimdjson
Browse files Browse the repository at this point in the history
  • Loading branch information
Wannes Boeykens committed Oct 13, 2024
1 parent 982deb2 commit efb515a
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 49 deletions.
40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,26 @@ We recommend to use [`orjson`](https://pypi.org/project/orjson) or
[`msgspec`](https://pypi.org/project/msgspec) for performance critical
applications:

| encode | json | jsonyx | msgspec | orjson | rapidjson | unit (μs) |
|:--------------------------------------------| -----:|-------:|--------:|--------:|----------:|----------:|
| List of 256 booleans | 4.82 | 4.11 | 1.16 | 1.00 | 3.12 | 1.85 |
| List of 256 ASCII strings | 14.71 | 12.73 | 1.67 | 1.00 | 10.12 | 3.64 |
| List of 256 floats | 23.47 | 23.54 | 1.38 | 1.00 | 24.87 | 8.57 |
| List of 256 dicts with 1 int | 10.87 | 11.17 | 1.48 | 1.00 | 6.30 | 8.54 |
| Medium complex object | 9.90 | 9.76 | 1.24 | 1.00 | 7.31 | 14.48 |
| List of 256 strings | 26.73 | 14.99 | 2.26 | 1.00 | 34.28 | 13.69 |
| Complex object | 7.80 | 5.55 | 1.00 | inf[^1] | 6.92 | 205.10 |
| Dict with 256 lists of 256 dicts with 1 int | 9.58 | 10.23 | 1.27 | 1.00 | 5.32 | 2517.22 |
| encode | json | jsonyx | msgspec | orjson | rapidjson | unit (μs) |
|:--------------------------------------------|------:|-------:|--------:|--------:|----------:|----------:|
| List of 256 booleans | 4.60 | 3.92 | 1.08 | 1.00 | 3.29 | 1.95 |
| List of 256 ASCII strings | 11.57 | 12.67 | 1.52 | 1.00 | 9.23 | 4.27 |
| List of 256 floats | 22.02 | 23.15 | 1.41 | 1.00 | 22.76 | 9.14 |
| List of 256 dicts with 1 int | 10.33 | 11.31 | 1.52 | 1.00 | 6.36 | 8.85 |
| Medium complex object | 9.68 | 10.13 | 1.22 | 1.00 | 6.71 | 15.26 |
| List of 256 strings | 21.84 | 11.63 | 2.12 | 1.00 | 30.21 | 14.97 |
| Complex object | 7.49 | 5.32 | 1.00 | inf[^1] | 6.71 | 207.61 |
| Dict with 256 lists of 256 dicts with 1 int | 8.40 | 9.14 | 1.20 | 1.00 | 5.04 | 2743.09 |

| decode | json | jsonyx | msgspec | orjson | rapidjson | unit (μs) |
|:--------------------------------------------|-----:|-------:|--------:|-------:|----------:|----------:|
| List of 256 booleans | 3.40 | 5.24 | 2.06 | 1.00 | 2.42 | 2.03 |
| List of 256 ASCII strings | 1.68 | 2.05 | 1.12 | 1.00 | 1.59 | 13.11 |
| List of 256 floats | 6.58 | 7.38 | 1.45 | 1.00 | 5.71 | 10.25 |
| List of 256 dicts with 1 int | 2.36 | 2.84 | 1.38 | 1.00 | 2.22 | 32.11 |
| Medium complex object | 2.89 | 3.70 | 1.23 | 1.00 | 2.62 | 33.99 |
| List of 256 strings | 1.02 | 1.00 | 2.74 | 2.04 | 2.99 | 64.38 |
| Complex object | 1.12 | 1.04 | 1.06 | 1.00 | 1.23 | 1061.41 |
| Dict with 256 lists of 256 dicts with 1 int | 1.66 | 1.91 | 1.14 | 1.00 | 1.47 | 17536.25 |
| decode | json | jsonyx | msgspec | orjson | rapidjson | simdjson | unit (μs) |
|:--------------------------------------------|------:|-------:|--------:|-------:|----------:|---------:|----------:|
| List of 256 booleans | 4.63 | 7.15 | 2.88 | 1.49 | 3.36 | 1.00 | 1.44 |
| List of 256 ASCII strings | 6.51 | 7.98 | 4.32 | 3.81 | 6.12 | 1.00 | 3.37 |
| List of 256 floats | 10.81 | 11.92 | 2.28 | 1.57 | 9.39 | 1.00 | 6.20 |
| List of 256 dicts with 1 int | 12.04 | 14.29 | 6.73 | 4.98 | 11.07 | 1.00 | 6.31 |
| Medium complex object | 11.84 | 15.33 | 5.02 | 4.00 | 10.61 | 1.00 | 8.25 |
| List of 256 strings | 4.68 | 3.22 | 8.06 | 6.49 | 9.21 | 1.00 | 20.25 |
| Complex object | 9.12 | 8.55 | 8.99 | 8.16 | 10.25 | 1.00 | 132.89 |
| Dict with 256 lists of 256 dicts with 1 int | 17.42 | 19.91 | 11.83 | 11.09 | 15.17 | 1.00 | 1752.60 |

[^1]: failed due to recursion error
4 changes: 3 additions & 1 deletion bench/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import msgspec
import orjson
import rapidjson
import simdjson
from tabulate import tabulate # type: ignore

import jsonyx
Expand Down Expand Up @@ -94,6 +95,7 @@
"orjson": orjson.loads,
# pylint: disable-next=I1101
"rapidjson": rapidjson.Decoder(),
"simdjson": simdjson.Parser().parse,
}


Expand Down Expand Up @@ -122,7 +124,7 @@ def _run_benchmark(
row.append(1_000_000 * unit)
results.append(row)

headers: list[str] = [name, *funcs.keys(), "unit\u00a0(\u03bcs)"]
headers: list[str] = [name, *funcs.keys(), "unit\xa0(\u03bcs)"]
print()
print(tabulate(results, headers, tablefmt="pipe", floatfmt=".02f"))
print(tabulate(results, headers, tablefmt="rst", floatfmt=".02f"))
Expand Down
1 change: 1 addition & 0 deletions bench/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
msgspec==0.18.6
orjson==3.10.7
pysimdjson==6.0.2
python-rapidjson==1.20
tabulate==0.9.0
56 changes: 28 additions & 28 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,34 +51,34 @@ performance and no dependencies.

.. rubric:: Benchmark

We recommend to use :pypi:`orjson` or :pypi:`msgspec` for performance critical
applications:

=========================================== ===== ====== ======= ======== ========= =========
encode json jsonyx msgspec orjson rapidjson unit (μs)
=========================================== ===== ====== ======= ======== ========= =========
List of 256 booleans 4.82 4.11 1.16 1.00 3.12 1.85
List of 256 ASCII strings 14.71 12.73 1.67 1.00 10.12 3.64
List of 256 floats 23.47 23.54 1.38 1.00 24.87 8.57
List of 256 dicts with 1 int 10.87 11.17 1.48 1.00 6.30 8.54
Medium complex object 9.90 9.76 1.24 1.00 7.31 14.48
List of 256 strings 26.73 14.99 2.26 1.00 34.28 13.69
Complex object 7.80 5.55 1.00 inf [1]_ 6.92 205.10
Dict with 256 lists of 256 dicts with 1 int 9.58 10.23 1.27 1.00 5.32 2517.22
=========================================== ===== ====== ======= ======== ========= =========

=========================================== ==== ====== ======= ====== ========= =========
decode json jsonyx msgspec orjson rapidjson unit (μs)
=========================================== ==== ====== ======= ====== ========= =========
List of 256 booleans 3.40 5.24 2.06 1.00 2.42 2.03
List of 256 ASCII strings 1.68 2.05 1.12 1.00 1.59 13.11
List of 256 floats 6.58 7.38 1.45 1.00 5.71 10.25
List of 256 dicts with 1 int 2.36 2.84 1.38 1.00 2.22 32.11
Medium complex object 2.89 3.70 1.23 1.00 2.62 33.99
List of 256 strings 1.02 1.00 2.74 2.04 2.99 64.38
Complex object 1.12 1.04 1.06 1.00 1.23 1061.41
Dict with 256 lists of 256 dicts with 1 int 1.66 1.91 1.14 1.00 1.47 17536.25
=========================================== ==== ====== ======= ====== ========= =========
We recommend to use :pypi:`orjson`, :pypi:`pysimdjson` or :pypi:`msgspec` for
performance critical applications:

=========================================== ===== ====== ======= ======== ========= =========
encode json jsonyx msgspec orjson rapidjson unit (μs)
=========================================== ===== ====== ======= ======== ========= =========
List of 256 booleans 4.60 3.92 1.08 1.00 3.29 1.95
List of 256 ASCII strings 11.57 12.67 1.52 1.00 9.23 4.27
List of 256 floats 22.02 23.15 1.41 1.00 22.76 9.14
List of 256 dicts with 1 int 10.33 11.31 1.52 1.00 6.36 8.85
Medium complex object 9.68 10.13 1.22 1.00 6.71 15.26
List of 256 strings 21.84 11.63 2.12 1.00 30.21 14.97
Complex object 7.49 5.32 1.00 inf [1]_ 6.71 207.61
Dict with 256 lists of 256 dicts with 1 int 8.40 9.14 1.20 1.00 5.04 2743.09
=========================================== ===== ====== ======= ======== ========= =========

=========================================== ===== ====== ======= ====== ========= ======== =========
decode json jsonyx msgspec orjson rapidjson simdjson unit (μs)
=========================================== ===== ====== ======= ====== ========= ======== =========
List of 256 booleans 4.63 7.15 2.88 1.49 3.36 1.00 1.44
List of 256 ASCII strings 6.51 7.98 4.32 3.81 6.12 1.00 3.37
List of 256 floats 10.81 11.92 2.28 1.57 9.39 1.00 6.20
List of 256 dicts with 1 int 12.04 14.29 6.73 4.98 11.07 1.00 6.31
Medium complex object 11.84 15.33 5.02 4.00 10.61 1.00 8.25
List of 256 strings 4.68 3.22 8.06 6.49 9.21 1.00 20.25
Complex object 9.12 8.55 8.99 8.16 10.25 1.00 132.89
Dict with 256 lists of 256 dicts with 1 int 17.42 19.91 11.83 11.09 15.17 1.00 1752.60
=========================================== ===== ====== ======= ====== ========= ======== =========

Check out the :doc:`get-started` section for further information, including how
to :ref:`install <installation>` the project.
Expand Down
1 change: 1 addition & 0 deletions src/jsonyx/_manipulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ def _run_select_query(
for target, key in nodes:
_check_query_key(target, key, allow_slice=True)

# TODO(Nice Zombies): exclude None
nodes = [
(target, key)
for (target, key) in nodes
Expand Down
1 change: 1 addition & 0 deletions src/jsonyx/test/test_run_select_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def __getitem__(item: slice) -> slice:
_slicer: _Slicer = _Slicer()


# TODO(Nice Zombies): test with None
@pytest.mark.parametrize(("node", "keep"), [
# List
(([], slice(0)), True),
Expand Down

0 comments on commit efb515a

Please sign in to comment.