From a1134dc914a337a2c49660969856a6a1cca55253 Mon Sep 17 00:00:00 2001 From: Ciro Date: Tue, 8 Nov 2022 10:07:18 -0300 Subject: [PATCH] add graph --- README.md | 107 ++++++++++++++++++++++++++++ bench/flask_plaintext.py | 14 ++++ bench/socketify_plaintext.py | 13 ++++ bench/uvicorn_guvicorn_plaintext.py | 17 +++++ examples/hello_world.py | 2 +- examples/websockets.py | 2 +- 6 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 bench/flask_plaintext.py create mode 100644 bench/socketify_plaintext.py create mode 100644 bench/uvicorn_guvicorn_plaintext.py diff --git a/README.md b/README.md index 21d8293..2130387 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,113 @@ This project aims to bring high performance PyPy3 web development and will bring We created and adapt the full C API from [uNetworking/uWebSockets](https://github.com/uNetworking/uWebSockets) and integrate libuv powered fetch and file IO, this same C API is used by [Bun](https://bun.sh/) + + +## Benchmark +HTTP requests per second (Linux x64) + +
+
+
+
124,943
+
socketify PyPy3
+
+
+
70,877
+
socketify Python3
+
+
+
30,173
+
gunicorn Python3
+
+
+
17,580
+
gunicorn PyPy3
+
+
+
+
+Runtime versions: PyPy3 7.3.9 and Python 3.10.7
+Framework versions: gunicorn 20.1.0 + uvicorn 0.19.0, socketify alpha
+Tested with ./http_load_test 40 127.0.0.1 8000 from [uSockets](https://github.com/uNetworking/uSockets) +Source code in [bench](https://github.com/cirospaciari/socketify.py/tree/main/bench) ## Install For macOS x64 & Silicon, Linux x64, Windows diff --git a/bench/flask_plaintext.py b/bench/flask_plaintext.py new file mode 100644 index 0000000..ecf9ee3 --- /dev/null +++ b/bench/flask_plaintext.py @@ -0,0 +1,14 @@ +import logging +logging.basicConfig() +logging.getLogger().setLevel(logging.CRITICAL) + +from flask import Flask +from waitress import serve + +app = Flask(__name__) + +@app.route('/') +def index(): + return "Hello, World!" + +serve(app, host='0.0.0.0', port=8000) diff --git a/bench/socketify_plaintext.py b/bench/socketify_plaintext.py new file mode 100644 index 0000000..36192e4 --- /dev/null +++ b/bench/socketify_plaintext.py @@ -0,0 +1,13 @@ +from socketify import App + +app = App() +app.get("/", lambda res, req: res.end("Hello World!")) +app.listen(8000, lambda config: print("Listening on port http://localhost:%d now\n" % config.port)) +app.run() + +# 124943.00 req/s socketify.py - PyPy3 7.3.9 +# 70877.75 req/s socketify.py - Python 3.10.7 +# 30173.75 req/s gunicorn 20.1.0 + uvicorn 0.19.0 - Python 3.10.7 +# 17580.25 req/s gunicorn 20.1.0 + uvicorn 0.19.0 - PyPy3 7.3.9 +# 8044.50 req/s flask 2.1.2 PyPy 7.3.9 +# 1957.50 req/s flask 2.1.2 Python 3.10.7 diff --git a/bench/uvicorn_guvicorn_plaintext.py b/bench/uvicorn_guvicorn_plaintext.py new file mode 100644 index 0000000..9335f42 --- /dev/null +++ b/bench/uvicorn_guvicorn_plaintext.py @@ -0,0 +1,17 @@ +async def app(scope, receive, send): + assert scope['type'] == 'http' + + await send({ + 'type': 'http.response.start', + 'status': 200, + 'headers': [ + [b'content-type', b'text/plain'], + ], + }) + await send({ + 'type': 'http.response.body', + 'body': b'Hello, world!', + }) + +#python3 -m gunicorn uvicorn_guvicorn_plaintext:app -w 1 -k uvicorn.workers.UvicornWorker +#pypy3 -m gunicorn uvicorn_guvicorn_plaintext:app -w 1 -k uvicorn.workers.UvicornWorker \ No newline at end of file diff --git a/examples/hello_world.py b/examples/hello_world.py index 80d037c..693bb01 100644 --- a/examples/hello_world.py +++ b/examples/hello_world.py @@ -1,6 +1,6 @@ from socketify import App app = App() -app.get("/", lambda res, req: res.end("Hello World socketify from Python!")) +app.get("/", lambda res, req: res.end("Hello World!")) app.listen(3000, lambda config: print("Listening on port http://localhost:%d now\n" % config.port)) app.run() \ No newline at end of file diff --git a/examples/websockets.py b/examples/websockets.py index c0b269c..37271a0 100644 --- a/examples/websockets.py +++ b/examples/websockets.py @@ -19,6 +19,6 @@ app.ws("/*", { 'drain': lambda ws: print('WebSocket backpressure: %s', ws.get_buffered_amount()), 'close': lambda ws, code, message: print('WebSocket closed') }) -app.any("/", lambda res,req: res.end("Nothing to see here!")) +app.any("/", lambda res,req: res.end("Nothing to see here!'")) app.listen(3000, lambda config: print("Listening on port http://localhost:%d now\n" % (config.port))) app.run() \ No newline at end of file