Skip to content

Instantly share code, notes, and snippets.

@iAnanich
Forked from mosquito/aiofile.ipynb
Last active September 30, 2024 21:59
Show Gist options
  • Save iAnanich/6dcb446575d26cd158440d4051f9eaf5 to your computer and use it in GitHub Desktop.
Save iAnanich/6dcb446575d26cd158440d4051f9eaf5 to your computer and use it in GitHub Desktop.
aiofile Benchmark
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"source": [
"# Benchmark aiofile\n",
"\n",
"Forked from: https://gist.github.com/mosquito/673a85c0be48af2ee2d382aaa0c1e3f0#file-aiofile-ipynb\n",
"snipper that was mentioned in https://github.com/mosquito/aiofile\n",
"\n",
"Library under test: https://github.com/mosquito/aiofile\n"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "markdown",
"source": [
"## Prepare"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "markdown",
"source": [
"### Fix async loop\n",
"\n",
"https://stackoverflow.com/questions/46827007/runtimeerror-this-event-loop-is-already-running-in-python"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 1,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: nest_asyncio in /home/ilya/anaconda3/envs/seismic_collector_3-12/lib/python3.12/site-packages (1.6.0)\r\n"
]
}
],
"source": [
"# https://stackoverflow.com/questions/46827007/runtimeerror-this-event-loop-is-already-running-in-python\n",
"try:\n",
" import nest_asyncio\n",
"except ImportError:\n",
" !pip install nest_asyncio\n",
" import nest_asyncio\n",
"finally:\n",
" nest_asyncio.apply()"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-09-30T21:26:27.964412206Z",
"start_time": "2024-09-30T21:26:26.451090567Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Imports"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"ExecuteTime": {
"end_time": "2024-09-30T21:26:31.165990112Z",
"start_time": "2024-09-30T21:26:31.124038019Z"
}
},
"outputs": [],
"source": [
"import asyncio\n",
"import aiofile\n",
"import hashlib\n",
"import os\n",
"import io\n",
"import time"
]
},
{
"cell_type": "markdown",
"source": [
"### Test functions"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 12,
"outputs": [],
"source": [
"async def test_aio_reader():\n",
" async with aiofile.AIOFile(FNAME, \"rb\") as afp:\n",
" reader = aiofile.Reader(afp, chunk_size=CHUNK_SIZE)\n",
" md5sum = hashlib.md5()\n",
"\n",
" async for chunk in reader:\n",
" if not chunk:\n",
" break\n",
"\n",
" md5sum.update(chunk)\n",
"\n",
" #return md5sum.hexdigest()\n",
"\n",
"\n",
"async def test_aio_writer():\n",
" async with aiofile.AIOFile(FNAME, \"wb+\") as afp:\n",
" writer = aiofile.Writer(afp)\n",
" payload = io.BytesIO(PAYLOAD)\n",
"\n",
" for chunk in iter(lambda: payload.read(CHUNK_SIZE), b''):\n",
" await writer(chunk)\n",
"\n",
"\n",
"async def test_reader(loop):\n",
" def blocking():\n",
" with open(FNAME, \"rb\") as fp:\n",
" md5sum = hashlib.md5()\n",
"\n",
" for _ in range(CHUNK_COUNT):\n",
" md5sum.update(fp.read(CHUNK_SIZE))\n",
"\n",
" #return md5sum.hexdigest()\n",
"\n",
" return await loop.run_in_executor(None, blocking)\n",
"\n",
"\n",
"async def test_writer(loop):\n",
" def blocking():\n",
" with open(FNAME, \"wb+\") as fp:\n",
" payload = io.BytesIO(PAYLOAD)\n",
"\n",
" for _ in range(CHUNK_COUNT):\n",
" fp.write(payload.read(CHUNK_SIZE))\n",
"\n",
" return await loop.run_in_executor(None, blocking)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-09-30T21:31:54.503412439Z",
"start_time": "2024-09-30T21:31:54.493100257Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"## Environment info"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 37,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"CPU: AMD Ryzen 3600\n",
"SSD: Samsung 980 500GB\n",
"\n"
]
}
],
"source": [
"print(\"\"\"\n",
"CPU: AMD Ryzen 3600\n",
"SSD: Samsung 980 500GB\n",
"\"\"\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-09-30T21:56:35.359775420Z",
"start_time": "2024-09-30T21:56:35.268341376Z"
}
}
},
{
"cell_type": "code",
"execution_count": 27,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Python 3.12.3\r\n",
"aiofile Version: 3.8.8\r\n",
"type(loop)=<class 'asyncio.unix_events._UnixSelectorEventLoop'>\n"
]
}
],
"source": [
"loop = asyncio.get_event_loop()\n",
"\n",
"!python --version\n",
"!echo \"aiofile\" $(pip show aiofile | grep Version)\n",
"print(f\"{type(loop)=}\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-09-30T21:44:38.793365634Z",
"start_time": "2024-09-30T21:44:37.239211520Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"## Run benchmark"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 38,
"outputs": [],
"source": [
"FNAME = \"/tmp/aiofile-benchmark.file\"\n",
"\n",
"CHUNK_SIZE = 1024 * 32 * 10\n",
"CHUNK_COUNT = 100\n",
"\n",
"PAYLOAD = os.urandom(CHUNK_SIZE * CHUNK_COUNT)\n",
"\n",
"\n",
"print(f\"{CHUNK_SIZE=}\")\n",
"print(f\"{CHUNK_COUNT=}\")\n",
"print(f\"{len(PAYLOAD)=}\")\n",
"print(\"==================\\n\")\n",
"\n",
"print(\"==================\")\n",
"print(\"Thread writer test\")\n",
"%timeit loop.run_until_complete(test_writer(loop))\n",
"print(\"==================\\n\")\n",
"\n",
"print(\"==================\")\n",
"print(\"Thread reader test\")\n",
"%timeit loop.run_until_complete(test_reader(loop))\n",
"print(\"==================\\n\")\n",
"\n",
"print(\"==================\")\n",
"print(\"AIO writer test\")\n",
"%timeit loop.run_until_complete(test_aio_writer())\n",
"print(\"==================\\n\")\n",
"\n",
"print(\"==================\")\n",
"print(\"AIO reader test\")\n",
"%timeit loop.run_until_complete(test_aio_reader())\n",
"print(\"==================\\n\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-09-30T21:56:47.695988990Z",
"start_time": "2024-09-30T21:56:47.541907781Z"
}
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
chunk size chunk count AIO writer test AIO reader test Thread writer test Thread reader test
1048576 200 300 ms ± 4.46 ms per loop 283 ms ± 2.57 ms per loop 296 ms ± 15.1 ms per loop 288 ms ± 13.7 ms per loop
1048576 100 156 ms ± 8.59 ms per loop 141 ms ± 527 μs per loop 138 ms ± 3.18 ms per loop 141 ms ± 1.29 ms per loop
327680 100 58.1 ms ± 1.03 ms per loop 45.5 ms ± 217 μs per loop 56.7 ms ± 2.69 ms per loop 54.7 ms ± 2.24 ms per loop
32768 1000 71.2 ms ± 1.01 ms per loop 60.5 ms ± 228 μs per loop 54.8 ms ± 3.22 ms per loop 57.9 ms ± 2.01 ms per loop
1024 100 3.53 ms ± 93.6 μs per loop 2.01 ms ± 38.3 μs per loop 532 μs ± 65.7 μs per loop 486 μs ± 4.32 μs per loop
CPU: AMD Ryzen 3600
SSD: Samsung 980 500GB
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Python 3.12.3
aiofile Version: 3.8.8
type(loop)=<class 'asyncio.unix_events._UnixSelectorEventLoop'>
====================================================================================================
CHUNK_SIZE=327680
CHUNK_COUNT=100
len(PAYLOAD)=32768000
==================
==================
Thread writer test
56.7 ms ± 2.69 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
==================
Thread reader test
54.7 ms ± 2.24 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
==================
AIO writer test
58.1 ms ± 1.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
==================
AIO reader test
45.5 ms ± 217 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
====================================================================================================
CHUNK_SIZE=1024
CHUNK_COUNT=100
len(PAYLOAD)=102400
==================
==================
Thread writer test
532 μs ± 65.7 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
==================
==================
Thread reader test
486 μs ± 4.32 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
==================
==================
AIO writer test
3.53 ms ± 93.6 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
==================
==================
AIO reader test
2.01 ms ± 38.3 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
==================
====================================================================================================
CHUNK_SIZE=32768
CHUNK_COUNT=1000
len(PAYLOAD)=32768000
==================
==================
Thread writer test
54.8 ms ± 3.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
==================
Thread reader test
57.9 ms ± 2.01 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
==================
AIO writer test
71.2 ms ± 1.01 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
==================
AIO reader test
60.5 ms ± 228 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
====================================================================================================
CHUNK_SIZE=1048576
CHUNK_COUNT=100
len(PAYLOAD)=104857600
==================
==================
Thread writer test
138 ms ± 3.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
==================
Thread reader test
141 ms ± 1.29 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
==================
AIO writer test
156 ms ± 8.59 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
==================
==================
AIO reader test
141 ms ± 527 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
==================
====================================================================================================
CHUNK_SIZE=1048576
CHUNK_COUNT=200
len(PAYLOAD)=209715200
==================
==================
Thread writer test
296 ms ± 15.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
==================
==================
Thread reader test
288 ms ± 13.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
==================
==================
AIO writer test
300 ms ± 4.46 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
==================
==================
AIO reader test
283 ms ± 2.57 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
==================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment