From a8585f768a5dad1b7364e6ef3e9a6868b6a42037 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Sun, 22 May 2016 14:38:42 -0400 Subject: [PATCH] readme: Add a section about uvloop performance --- README.rst | 20 +++++++++++++++++--- performance.png | Bin 0 -> 26253 bytes 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 performance.png diff --git a/README.rst b/README.rst index 1b6645c..dfbb1c6 100644 --- a/README.rst +++ b/README.rst @@ -9,13 +9,27 @@ uvloop is a fast, drop-in replacement of the built-in asyncio event loop. uvloop is implemented in Cython and uses libuv under the hood. -Read more about uvloop here: -http://magic.io/blog/uvloop-blazing-fast-python-networking/ - The project documentation can be found `here `_. +Performance +----------- + +uvloop makes asyncio 2-4x times faster. + +.. image:: performance.png + :target: http://magic.io/blog/uvloop-blazing-fast-python-networking/ + +The above chart shows the performance of an echo server with different +message sizes. The *sockets* benchmark uses ``loop.sock_recv()`` and +``loop.sock_sendall()`` methods; the *streams* benchmark uses asyncio +high-level streams, created by the ``asyncio.start_server()`` function; +and the *protocol* benchmark uses ``loop.create_server()`` with a simple +echo protocol. Read more about uvloop performance +`here `_. + + Installation ------------ diff --git a/performance.png b/performance.png new file mode 100644 index 0000000000000000000000000000000000000000..6bc573a65addfe6cf75bba8dfa8cfa320ab5c16d GIT binary patch literal 26253 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 literal 0 HcmV?d00001