Skip to content

Aiohttp switch to orjson #9767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 7, 2025

Conversation

Reskov
Copy link
Contributor

@Reskov Reskov commented Apr 2, 2025

Switch to orjson since it outperforms ujson https://dev.to/dollardhingra/benchmarking-python-json-serializers-json-vs-ujson-vs-orjson-1o16

pip install aiohttp orjson ujson

from aiohttp.web import Response
from aiohttp import web
import orjson
import ujson

def json_response(payload):
    return Response(
        body=orjson.dumps(payload),
        content_type="application/json",
    )


async def orjson_handler(request):
    return json_response(
        {'message': 'Hello, World!'},
    )

async def ujson_handler(request):
    return web.json_response(
        text=ujson.dumps({'message': 'Hello, World!'}),
        content_type="application/json",
    )

app = web.Application()
app.router.add_get('/orjson', orjson_handler)
app.router.add_get('/ujson', ujson_handler)

if __name__ == '__main__':
    web.run_app(app, port=8080)

Local benchmark

 wrk -t8 -c20 -d20s http://localhost:8080/orjson 
Running 20s test @ http://localhost:8080/orjson
  8 threads and 20 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   622.93us    1.14ms  38.03ms   99.60%
    Req/Sec     3.56k   165.63     3.94k    82.90%
  569116 requests in 20.10s, 93.35MB read
Requests/sec:  28310.04
Transfer/sec:      4.64MB
 wrk -t8 -c20 -d20s http://localhost:8080/ujson
Running 20s test @ http://localhost:8080/ujson
  8 threads and 20 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   805.26us    3.19ms  77.12ms   99.31%
    Req/Sec     3.48k   218.00     3.76k    96.52%
  556324 requests in 20.10s, 99.21MB read
Requests/sec:  27675.67
Transfer/sec:      4.94MB

@Reskov
Copy link
Contributor Author

Reskov commented Apr 4, 2025

Builds fail on /updates, but I'm not sure if switching the json response library can cause this issue. Maybe it is because of the update isn't triggered when randomNumber matching previous, and we need to have something similar.

flag_modified(world, "randomnumber")

also looks like this original code may produce duplicate ids

updates = [(randint(1, 10000), randint(1, 10000)) for _ in range(num_queries)]

@Reskov
Copy link
Contributor Author

Reskov commented Apr 7, 2025

@Dreamsorcerer please take a look.

  1. The benchmark performance are unstable locally ./tfb --mode verify --test aiohttp So I can not measure the actual impact of switching from ujson to orjson. But orjson.dumps outperforms ujson on a separate benchmark.

  2. The changes of the db is necessary to prevent framework tests flaky

  3. psycopg2 library is not used.

@Dreamsorcerer
Copy link
Contributor

Changes are now overlapping my PR, but yeah, looks good to me. Either can be merged and then conflicts fixed.

@Dreamsorcerer
Copy link
Contributor

Dreamsorcerer commented Apr 7, 2025

Note that the places your last commit deviates from my changes though, I already micro-benchmarked.
e.g.

> python3 -m timeit 'from random import randint, sample; a = sample(range(1, 10001), 1000); a.sort()' 'for x in a: y = randint(1, 10000)'
100 loops, best of 5: 2.14 msec per loop
> python3 -m timeit 'from random import randint, sample; a = sample(range(1, 10001), 1000); a.sort()' 'x = tuple(zip(a, sample(range(1, 10001), 1000)))
              for y,z in x: pass'
200 loops, best of 5: 1.79 msec per loop

So, maybe better to revert that commit and just let my PR get merged after this one.

@msmith-techempower msmith-techempower merged commit dc369c8 into TechEmpower:master Apr 7, 2025
3 checks passed
@Reskov Reskov mentioned this pull request Apr 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants