Skip to content

Instantly share code, notes, and snippets.

@samuelcolvin
Created January 17, 2024 17:21
Show Gist options
  • Save samuelcolvin/79217dbbf93f99ffc73fbfa906f7cdd0 to your computer and use it in GitHub Desktop.
Save samuelcolvin/79217dbbf93f99ffc73fbfa906f7cdd0 to your computer and use it in GitHub Desktop.
import timeit
from pathlib import Path
import orjson
import pydantic_core
import ujson
import json
cases = [
('medium_response', Path('../jiter/benches/medium_response.json').read_bytes()),
('massive_ints_array', Path('../jiter/benches/massive_ints_array.json').read_bytes()),
('array_short_strings', '[{}]'.format(', '.join('"123"' for _ in range(100_000)))),
('object_short_strings', '{%s}' % ', '.join(f'"{i}": "{i}x"' for i in range(100_000))),
('array_short_arrays', '[{}]'.format(', '.join('["a", "b", "c", "d"]' for _ in range(10_000)))),
]
def run_bench(func, d):
# assert func(d) == json.loads(d)
# assert repr(func(json_data)) == repr(json.loads(json_data))
timer = timeit.Timer(
'func(json_data)', setup='', globals={'func': func, 'json_data': d}
)
n, t = timer.autorange()
iter_time = t / n
# print(f'{func.__module__}.{func.__name__}', n)
return iter_time
for name, json_data in cases:
print(f'Case: {name}')
times = [
('orjson', run_bench(orjson.loads, json_data)),
('pydantic', run_bench(lambda d: pydantic_core.from_json(d, cache_strings=True), json_data)),
('ujson', run_bench(ujson.loads, json_data)),
('json', run_bench(json.loads, json_data)),
]
times.sort(key=lambda x: x[1])
best = times[0][1]
print(f'{"package":>12} | {"time µs":>10} | slowdown')
print(f'{"-" * 13}|{"-" * 12}|{"-" * 9}')
for name, time in times:
print(f'{name:>12} | {time * 1_000_000:10.2f} | {time / best:8.2f}')
print('')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment