mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 10:05:28 +03:00
benchs
This commit is contained in:
@@ -1 +1 @@
|
||||
from .pre_cycle_setup import *
|
||||
from .core import *
|
||||
@@ -0,0 +1 @@
|
||||
from .pre_cycle_setup import *
|
||||
@@ -7,12 +7,12 @@ __all__ = [
|
||||
]
|
||||
|
||||
from argenta import App
|
||||
from argenta.router import Router
|
||||
from argenta.command.models import Command
|
||||
from argenta.response import Response
|
||||
from argenta.router import Router
|
||||
|
||||
from ..models import benchmark
|
||||
from ..utils import get_time_of_pre_cycle_setup
|
||||
from ..registry import benchmark
|
||||
|
||||
|
||||
@benchmark(type_="pre_cycle_setup", description="With no aliases")
|
||||
@@ -0,0 +1,110 @@
|
||||
__all__ = [
|
||||
"Benchmark",
|
||||
"Benchmarks",
|
||||
"BenchmarkResult",
|
||||
"benchmark"
|
||||
]
|
||||
|
||||
from dataclasses import dataclass
|
||||
from decimal import Decimal
|
||||
from typing import Callable, ClassVar, overload, override
|
||||
|
||||
BenchmarkAsFunc = Callable[[], float]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BenchmarkResult:
|
||||
type_: str
|
||||
name: str
|
||||
description: str
|
||||
iterations: int
|
||||
avg_time: Decimal
|
||||
|
||||
|
||||
class Benchmark:
|
||||
def __init__(
|
||||
self,
|
||||
func: BenchmarkAsFunc,
|
||||
*,
|
||||
type_: str,
|
||||
name: str,
|
||||
description: str,
|
||||
iterations: int
|
||||
) -> None:
|
||||
self.func = func
|
||||
self.type_ = type_
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.iterations = iterations
|
||||
|
||||
def run(self) -> float:
|
||||
return self.func()
|
||||
|
||||
@override
|
||||
def __repr__(self) -> str:
|
||||
return f'Benchmark<{self.type_=}, {self.name=}, {self.description=}, {self.iterations=}>'
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return f'Benchmark({self.type_=}, {self.name=}, {self.description=}, {self.iterations=})'
|
||||
|
||||
|
||||
class Benchmarks:
|
||||
_benchmarks: ClassVar[list[Benchmark]] = []
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def register(
|
||||
cls,
|
||||
call: BenchmarkAsFunc,
|
||||
*,
|
||||
type_: str = "",
|
||||
description: str = "",
|
||||
iterations: int = 100,
|
||||
) -> BenchmarkAsFunc:
|
||||
...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def register(
|
||||
cls,
|
||||
call: None = None,
|
||||
*,
|
||||
type_: str = "",
|
||||
description: str = "",
|
||||
iterations: int = 100,
|
||||
) -> Callable[[BenchmarkAsFunc], BenchmarkAsFunc]:
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def register(
|
||||
cls,
|
||||
call: BenchmarkAsFunc | None = None,
|
||||
*,
|
||||
type_: str = "",
|
||||
description: str = "",
|
||||
iterations: int = 100,
|
||||
) -> Callable[[BenchmarkAsFunc], BenchmarkAsFunc] | BenchmarkAsFunc:
|
||||
def decorator(func: BenchmarkAsFunc) -> BenchmarkAsFunc:
|
||||
cls._benchmarks.append(
|
||||
Benchmark(
|
||||
func,
|
||||
type_=type_,
|
||||
name=func.__name__,
|
||||
description=description or f'description for {func.__name__} with {iterations} iterations',
|
||||
iterations=iterations
|
||||
)
|
||||
)
|
||||
return func
|
||||
|
||||
if call is None:
|
||||
return decorator
|
||||
else:
|
||||
return decorator(call)
|
||||
|
||||
@classmethod
|
||||
def get_benchmarks(cls) -> list[Benchmark]:
|
||||
return cls._benchmarks
|
||||
|
||||
|
||||
benchmark = Benchmarks.register
|
||||
@@ -0,0 +1,89 @@
|
||||
__all__ = [
|
||||
"get_time_of_pre_cycle_setup",
|
||||
"attempts_to_average",
|
||||
"run_benchmark",
|
||||
"run_all_benchmarks",
|
||||
"get_kernel_version"
|
||||
]
|
||||
|
||||
import io
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import time
|
||||
from concurrent.futures import ProcessPoolExecutor
|
||||
from contextlib import redirect_stdout
|
||||
from decimal import ROUND_HALF_UP, Decimal
|
||||
|
||||
from argenta import App
|
||||
from .models import Benchmark, BenchmarkResult, Benchmarks
|
||||
|
||||
|
||||
def get_time_of_pre_cycle_setup(app: App) -> float:
|
||||
start = time.perf_counter()
|
||||
with redirect_stdout(io.StringIO()):
|
||||
app._pre_cycle_setup() # pyright: ignore[reportPrivateUsage]
|
||||
end = time.perf_counter()
|
||||
return (end - start) * 1000 # as milliseconds
|
||||
|
||||
|
||||
def get_kernel_version() -> dict[str, str]:
|
||||
system = platform.system()
|
||||
|
||||
if system == "Windows":
|
||||
ver = sys.getwindowsversion()
|
||||
kernel_version = f"{ver.major}.{ver.minor}.{ver.build}"
|
||||
|
||||
if ver.build >= 22000:
|
||||
product_name = "Windows 11"
|
||||
else:
|
||||
product_name = "Windows 10"
|
||||
|
||||
return {
|
||||
'kernel_version': kernel_version,
|
||||
'product_name': product_name
|
||||
}
|
||||
|
||||
elif system == "Linux":
|
||||
return {
|
||||
'kernel_version': platform.release(),
|
||||
'product_name': platform.system()
|
||||
}
|
||||
|
||||
elif system == "Darwin":
|
||||
return {
|
||||
'kernel_version': platform.release(),
|
||||
'product_name': f"macOS {platform.mac_ver()[0]}"
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'kernel_version': platform.release(),
|
||||
'product_name': platform.system(),
|
||||
}
|
||||
|
||||
|
||||
def attempts_to_average(bench_attempts: list[float], iterations: int) -> Decimal:
|
||||
return Decimal(sum(bench_attempts) / iterations).quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)
|
||||
|
||||
|
||||
def run_all_benchmarks() -> dict[str, list[BenchmarkResult]]:
|
||||
all_benchmarks: list[Benchmark] = Benchmarks.get_benchmarks()
|
||||
|
||||
workers = os.cpu_count() or 1
|
||||
with ProcessPoolExecutor(max_workers=workers) as executor:
|
||||
results = executor.map(run_benchmark, all_benchmarks)
|
||||
|
||||
type_paired_benchmarks: dict[str, list[BenchmarkResult]] = {}
|
||||
|
||||
for result in results:
|
||||
type_paired_benchmarks.setdefault(result.type_, []).append(result)
|
||||
|
||||
return type_paired_benchmarks
|
||||
|
||||
|
||||
def run_benchmark(benchmark: Benchmark) -> BenchmarkResult:
|
||||
bench_attempts: list[float] = []
|
||||
for _ in range(benchmark.iterations):
|
||||
bench_attempts.append(benchmark.run())
|
||||
avg = attempts_to_average(bench_attempts, benchmark.iterations)
|
||||
return BenchmarkResult(benchmark.type_, benchmark.name, benchmark.description, benchmark.iterations, avg)
|
||||
Reference in New Issue
Block a user