python-kasa/devtools/perftest.py
Teemu R d75e1adaba
Add perftest to devtools (#236)
* Add perftest to devtools

* Add example output from the perf script

* Rename to avoid pytest collection

* Fix git mv failing to remove the original file..
2021-10-13 19:22:24 +02:00

94 lines
2.4 KiB
Python

"""Script for testing update performance on devices."""
import asyncio
import time
import asyncclick as click
import pandas as pd
from kasa import Discover
async def _update(dev, lock=None):
if lock is not None:
await lock.acquire()
await asyncio.sleep(2)
try:
start_time = time.time()
# print("%s >> Updating" % id(dev))
await dev.update()
# print("%s >> done in %s" % (id(dev), time.time() - start_time))
return {"id": f"{id(dev)}-{dev.model}", "took": (time.time() - start_time)}
finally:
if lock is not None:
lock.release()
async def _update_concurrently(devs):
start_time = time.time()
update_futures = [asyncio.ensure_future(_update(dev)) for dev in devs]
await asyncio.gather(*update_futures)
return {"type": "concurrently", "took": (time.time() - start_time)}
async def _update_sequentially(devs):
start_time = time.time()
for dev in devs:
await _update(dev)
return {"type": "sequential", "took": (time.time() - start_time)}
@click.command()
@click.argument("addrs", nargs=-1)
@click.option("--rounds", default=5)
async def main(addrs, rounds):
"""Test update performance on given devices."""
print(f"Running {rounds} rounds on {addrs}")
devs = []
for addr in addrs:
try:
dev = await Discover.discover_single(addr)
devs.append(dev)
except Exception as ex:
print(f"unable to add {addr}: {ex}")
data = []
test_gathered = True
if test_gathered:
print("=== Testing using gather on all devices ===")
for i in range(rounds):
data.append(await _update_concurrently(devs))
await asyncio.sleep(2)
await asyncio.sleep(5)
for i in range(rounds):
data.append(await _update_sequentially(devs))
await asyncio.sleep(2)
df = pd.DataFrame(data)
print(df.groupby("type").describe())
print("=== Testing per-device performance ===")
futs = []
data = []
locks = {dev: asyncio.Lock() for dev in devs}
for i in range(rounds):
for dev in devs:
futs.append(asyncio.ensure_future(_update(dev, locks[dev])))
for fut in asyncio.as_completed(futs):
res = await fut
data.append(res)
df = pd.DataFrame(data)
print(df.groupby("id").describe())
if __name__ == "__main__":
main(_anyio_backend="asyncio")