From 6d7ba58f880be618ade07f8ea080fe8c4bf8a896 Mon Sep 17 00:00:00 2001 From: cyfraeviolae Date: Wed, 3 Apr 2024 03:10:44 -0400 Subject: venv --- .../site-packages/aiosqlite/tests/perf.py | 203 +++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 venv/lib/python3.11/site-packages/aiosqlite/tests/perf.py (limited to 'venv/lib/python3.11/site-packages/aiosqlite/tests/perf.py') diff --git a/venv/lib/python3.11/site-packages/aiosqlite/tests/perf.py b/venv/lib/python3.11/site-packages/aiosqlite/tests/perf.py new file mode 100644 index 0000000..08f0335 --- /dev/null +++ b/venv/lib/python3.11/site-packages/aiosqlite/tests/perf.py @@ -0,0 +1,203 @@ +# Copyright 2022 Amethyst Reese +# Licensed under the MIT license + +""" +Simple perf tests for aiosqlite and the asyncio run loop. +""" +import string +import tempfile +import time + +from unittest import IsolatedAsyncioTestCase as TestCase + +import aiosqlite +from .smoke import setup_logger + +TEST_DB = ":memory:" +TARGET = 2.0 +RESULTS = {} + + +def timed(fn, name=None): + """ + Decorator for perf testing a block of async code. + + Expects the wrapped function to return an async generator. + The generator should do setup, then yield when ready to start perf testing. + The decorator will then pump the generator repeatedly until the target + time has been reached, then close the generator and print perf results. + """ + + name = name or fn.__name__ + + async def wrapper(*args, **kwargs): + gen = fn(*args, **kwargs) + + await gen.asend(None) + count = 0 + before = time.time() + + while True: + count += 1 + value = time.time() - before < TARGET + try: + if value: + await gen.asend(value) + else: + await gen.aclose() + break + + except StopAsyncIteration: + break + + except Exception as e: + print(f"exception occurred: {e}") + return + + duration = time.time() - before + + RESULTS[name] = (count, duration) + + return wrapper + + +class PerfTest(TestCase): + @classmethod + def setUpClass(cls): + print(f"Running perf tests for at least {TARGET:.1f}s each...") + setup_logger() + + @classmethod + def tearDownClass(cls): + print(f"\n{'Perf Test':<25} Iterations Duration {'Rate':>11}") + for name in sorted(RESULTS): + count, duration = RESULTS[name] + rate = count / duration + name = name.replace("test_", "") + print(f"{name:<25} {count:>10} {duration:>7.1f}s {rate:>9.1f}/s") + + @timed + async def test_connection_memory(self): + while True: + yield + async with aiosqlite.connect(TEST_DB): + pass + + @timed + async def test_connection_file(self): + with tempfile.NamedTemporaryFile(delete=False) as tf: + path = tf.name + tf.close() + + async with aiosqlite.connect(path) as db: + await db.execute( + "create table perf (i integer primary key asc, k integer)" + ) + await db.execute("insert into perf (k) values (2), (3)") + await db.commit() + + while True: + yield + async with aiosqlite.connect(path): + pass + + @timed + async def test_atomics(self): + async with aiosqlite.connect(TEST_DB) as db: + await db.execute("create table perf (i integer primary key asc, k integer)") + await db.execute("insert into perf (k) values (2), (3)") + await db.commit() + + while True: + yield + async with db.execute("select last_insert_rowid()") as cursor: + await cursor.fetchone() + + @timed + async def test_inserts(self): + async with aiosqlite.connect(TEST_DB) as db: + await db.execute("create table perf (i integer primary key asc, k integer)") + await db.commit() + + while True: + yield + await db.execute("insert into perf (k) values (1), (2), (3)") + await db.commit() + + @timed + async def test_insert_ids(self): + async with aiosqlite.connect(TEST_DB) as db: + await db.execute("create table perf (i integer primary key asc, k integer)") + await db.commit() + + while True: + yield + cursor = await db.execute("insert into perf (k) values (1)") + await cursor.execute("select last_insert_rowid()") + await cursor.fetchone() + await db.commit() + + @timed + async def test_insert_macro_ids(self): + async with aiosqlite.connect(TEST_DB) as db: + await db.execute("create table perf (i integer primary key asc, k integer)") + await db.commit() + + while True: + yield + await db.execute_insert("insert into perf (k) values (1)") + await db.commit() + + @timed + async def test_select(self): + async with aiosqlite.connect(TEST_DB) as db: + await db.execute("create table perf (i integer primary key asc, k integer)") + for i in range(100): + await db.execute("insert into perf (k) values (%d)" % (i,)) + await db.commit() + + while True: + yield + cursor = await db.execute("select i, k from perf") + assert len(await cursor.fetchall()) == 100 + + @timed + async def test_select_macro(self): + async with aiosqlite.connect(TEST_DB) as db: + await db.execute("create table perf (i integer primary key asc, k integer)") + for i in range(100): + await db.execute("insert into perf (k) values (%d)" % (i,)) + await db.commit() + + while True: + yield + assert len(await db.execute_fetchall("select i, k from perf")) == 100 + + async def test_iterable_cursor_perf(self): + async with aiosqlite.connect(TEST_DB) as db: + await db.execute( + "create table ic_perf (" + "i integer primary key asc, k integer, a integer, b integer, c char(16))" + ) + for batch in range(128): # add 128k rows + r_start = batch * 1024 + await db.executemany( + "insert into ic_perf (k, a, b, c) values(?, 1, 2, ?)", + [ + *[ + (i, string.ascii_lowercase) + for i in range(r_start, r_start + 1024) + ] + ], + ) + await db.commit() + + async def test_perf(chunk_size: int): + while True: + async with db.execute("SELECT * FROM ic_perf") as cursor: + cursor.iter_chunk_size = chunk_size + async for _ in cursor: + yield + + for chunk_size in [2**i for i in range(4, 11)]: + await timed(test_perf, f"iterable_cursor @ {chunk_size}")(chunk_size) -- cgit v1.2.3