Skip to content

Instantly share code, notes, and snippets.

@methane
Created May 1, 2025 08:53
Show Gist options
  • Select an option

  • Save methane/e080ec9783db2a313f40a2b9e1837e72 to your computer and use it in GitHub Desktop.

Select an option

Save methane/e080ec9783db2a313f40a2b9e1837e72 to your computer and use it in GitHub Desktop.
"""JSON benchmark."""
# Original: https://github.com/nineteendo/jsonyx/blob/main/bench/__main__.py
# Copy https://github.com/nineteendo/jsonyx/blob/main/bench/sample.json to same directory
from __future__ import annotations
import json
from pathlib import Path
from random import random, seed
from sys import maxsize
from typing import Any
from itertools import repeat
import pyperf
seed(0)
_USER: dict[str, Any] = {
"userId": 3381293,
"age": 213,
"username": "johndoe",
"fullname": "John Doe the Second",
"isAuthorized": True,
"liked": 31231.31231202,
"approval": 31.1471,
"jobs": [1, 2],
"currJob": None,
}
_FRIENDS: list[dict[str, Any]] = [_USER] * 8
_ENCODE_CASES: dict[str, Any] = {
"List of 256 booleans": [True] * 256,
"List of 256 ASCII strings": [
"A pretty long string which is in a list",
]
* 256,
"List of 256 floats": [
maxsize * random()
for _ in range(256) # noqa: S311
],
"List of 256 dicts with 1 int": [
{str(random() * 20): int(random() * 1_000_000)} # noqa: S311
for _ in range(256)
],
"Medium complex object": [[_USER, _FRIENDS]] * 6,
"List of 256 strings": [
"\u0646\u0638\u0627\u0645 \u0627\u0644\u062d\u0643\u0645 \u0633\u0644"
"\u0637\u0627\u0646\u064a \u0648\u0631\u0627\u062b\u064a \u0641\u064a "
"\u0627\u0644\u0630\u0643\u0648\u0631 \u0645\u0646 \u0630\u0631\u064a"
"\u0629 \u0627\u0644\u0633\u064a\u062f \u062a\u0631\u0643\u064a \u0628"
"\u0646 \u0633\u0639\u064a\u062f \u0628\u0646 \u0633\u0644\u0637\u0627"
"\u0646 \u0648\u064a\u0634\u062a\u0631\u0637 \u0641\u064a\u0645\u0646 "
"\u064a\u062e\u062a\u0627\u0631 \u0644\u0648\u0644\u0627\u064a\u0629 "
"\u0627\u0644\u062d\u0643\u0645 \u0645\u0646 \u0628\u064a\u0646\u0647"
"\u0645 \u0627\u0646 \u064a\u0643\u0648\u0646 \u0645\u0633\u0644\u0645"
"\u0627 \u0631\u0634\u064a\u062f\u0627 \u0639\u0627\u0642\u0644\u0627 "
"\u064b\u0648\u0627\u0628\u0646\u0627 \u0634\u0631\u0639\u064a\u0627 "
"\u0644\u0627\u0628\u0648\u064a\u0646 \u0639\u0645\u0627\u0646\u064a"
"\u064a\u0646 ",
]
* 256,
"Complex object": json.loads((Path(__file__).parent / "sample.json").read_text()),
"Dict with 256 lists of 256 dicts with 1 int": {
str(random() * 20): [ # noqa: S311
{str(random() * 20): int(random() * 1_000_000)} # noqa: S311
for _ in range(256)
]
for _ in range(256)
},
}
_DECODE_CASES: dict[str, Any] = {
case: json.dumps(obj) for case, obj in _ENCODE_CASES.items()
}
for case, obj in _ENCODE_CASES.items():
s = json.dumps(obj, ensure_ascii=False)
if _DECODE_CASES[case] != s:
_DECODE_CASES[case + "ensure_ascii=False"] = s
N = 100
def bench_json_dumps_ascii(data):
for _ in repeat(None, N):
json.dumps(data)
def bench_json_dumps(data):
for _ in repeat(None, N):
json.dumps(data)
def bench_json_loads(data):
for _ in repeat(None, N):
json.loads(data)
def main():
runner = pyperf.Runner()
runner.metadata["description"] = "Benchmark json.dumps() and json.loads()"
for name, data in _ENCODE_CASES.items():
runner.bench_func(f"json_dumps: {name}", bench_json_dumps_ascii, data, inner_loops=N)
for name, data in _ENCODE_CASES.items():
runner.bench_func(f"json_dumps(ensure_ascii=False): {name}", bench_json_dumps, data, inner_loops=N)
for name, data in _DECODE_CASES.items():
runner.bench_func(f"json_loads: {name}", bench_json_loads, data, inner_loops=N)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment