mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 01:55:29 +03:00
benchs
This commit is contained in:
@@ -1 +0,0 @@
|
||||
from .benchmarks import *
|
||||
+8
-41
@@ -1,48 +1,15 @@
|
||||
from concurrent.futures import ProcessPoolExecutor
|
||||
import os
|
||||
from argenta import App, Orchestrator
|
||||
from argenta.app import DynamicDividingLine
|
||||
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
from .handlers import router
|
||||
|
||||
from metrics.utils import run_benchmark, BenchmarkResult
|
||||
from .registry import Benchmarks, Benchmark
|
||||
app = App(initial_message="metrics", prompt=">>> ", dividing_line=DynamicDividingLine('~'))
|
||||
orchestrator = Orchestrator()
|
||||
|
||||
|
||||
def main():
|
||||
console = Console()
|
||||
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)
|
||||
|
||||
for type_, benchmarks in type_paired_benchmarks.items():
|
||||
header_text = Text(f"TYPE: {type_.upper()}", style="bold magenta")
|
||||
console.print(Panel(header_text, expand=False, border_style="magenta"))
|
||||
|
||||
table = Table(show_header=True, header_style="bold cyan", border_style="blue", show_lines=True)
|
||||
table.add_column("Name", style="green")
|
||||
table.add_column("Description", style="dim")
|
||||
table.add_column("Iterations", justify="right")
|
||||
table.add_column("Avg Time (ms)", justify="right", style="bold yellow")
|
||||
|
||||
for benchmark in benchmarks:
|
||||
table.add_row(
|
||||
benchmark.name,
|
||||
benchmark.description,
|
||||
str(benchmark.iterations),
|
||||
str(benchmark.avg_time)
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
console.print()
|
||||
def main() -> None:
|
||||
app.include_router(router)
|
||||
orchestrator.start_polling(app)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -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")
|
||||
@@ -1,14 +1,26 @@
|
||||
__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,
|
||||
@@ -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)
|
||||
@@ -0,0 +1,70 @@
|
||||
import platform
|
||||
import cpuinfo
|
||||
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.table import Table
|
||||
from rich.text import Text
|
||||
|
||||
from argenta.command.models import Command
|
||||
from argenta.response import Response
|
||||
from argenta.router import Router
|
||||
from .benchmarks.models import BenchmarkResult
|
||||
from .benchmarks.utils import run_all_benchmarks, get_kernel_version
|
||||
|
||||
console = Console()
|
||||
router = Router(title="Metrics commands:")
|
||||
|
||||
|
||||
@router.command(Command("all-print", description="Print all benchmarks results"))
|
||||
def all_print_handler(_: Response) -> None:
|
||||
cpu_info = cpuinfo.get_cpu_info()
|
||||
os_info = get_kernel_version()
|
||||
|
||||
table = Table(show_header=True, header_style="bold cyan", border_style="blue", show_lines=True)
|
||||
table.add_column("Parameter", style="green")
|
||||
table.add_column("Value", style="yellow")
|
||||
|
||||
table.add_row("OS", platform.system())
|
||||
table.add_row("OS Name", os_info['product_name'])
|
||||
table.add_row("OS Kernel Version", os_info['kernel_version'])
|
||||
table.add_row("Architecture", cpu_info['arch'])
|
||||
table.add_row("Processor", cpu_info['brand_raw'])
|
||||
table.add_row("Python Version", cpu_info['python_version'])
|
||||
table.add_row("Python Implementation", platform.python_implementation())
|
||||
|
||||
header_text = Text("SYSTEM INFO", style="bold magenta")
|
||||
console.print(Panel(header_text, expand=False, border_style="magenta"))
|
||||
console.print(table, end="\n\n")
|
||||
|
||||
type_paired_benchmarks: dict[str, list[BenchmarkResult]] = run_all_benchmarks()
|
||||
|
||||
for type_, benchmarks in type_paired_benchmarks.items():
|
||||
header_text = Text(f"TYPE: {type_.upper()}", style="bold magenta")
|
||||
console.print(Panel(header_text, expand=False, border_style="magenta"))
|
||||
|
||||
table = Table(show_header=True, header_style="bold cyan", border_style="blue", show_lines=True)
|
||||
table.add_column("Name", style="green")
|
||||
table.add_column("Description", style="dim")
|
||||
table.add_column("Iterations", justify="right")
|
||||
table.add_column("Avg Time (ms)", justify="right", style="bold yellow")
|
||||
|
||||
for benchmark in benchmarks:
|
||||
table.add_row(
|
||||
benchmark.name,
|
||||
benchmark.description,
|
||||
str(benchmark.iterations),
|
||||
str(benchmark.avg_time)
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
||||
|
||||
@router.command(Command("release-generate", description="Generate release report"))
|
||||
def release_generate_handler(_: Response) -> None:
|
||||
console.print("[yellow]Release report generation not implemented yet[/yellow]")
|
||||
|
||||
|
||||
@router.command(Command("diagrams-generate", description="Generate diagrams"))
|
||||
def diagrams_generate_handler(_: Response) -> None:
|
||||
console.print("[yellow]Diagrams generation not implemented yet[/yellow]")
|
||||
@@ -1,44 +0,0 @@
|
||||
__all__ = [
|
||||
"get_time_of_pre_cycle_setup",
|
||||
"attempts_to_average",
|
||||
"run_benchmark",
|
||||
"BenchmarkResult"
|
||||
]
|
||||
|
||||
import io
|
||||
from contextlib import redirect_stdout
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from decimal import Decimal, ROUND_HALF_UP
|
||||
|
||||
from argenta import App
|
||||
from metrics.registry import Benchmark
|
||||
|
||||
|
||||
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 attempts_to_average(bench_attempts: list[float], iterations: int) -> Decimal:
|
||||
return Decimal(sum(bench_attempts) / iterations).quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BenchmarkResult:
|
||||
type_: str
|
||||
name: str
|
||||
description: str
|
||||
iterations: int
|
||||
avg_time: Decimal
|
||||
|
||||
|
||||
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)
|
||||
@@ -35,6 +35,9 @@ tests = [
|
||||
"pytest-cov>=7.0.0",
|
||||
"pytest-mock>=3.15.1",
|
||||
]
|
||||
metrics = [
|
||||
"py-cpuinfo>=9.0.0",
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
exclude = [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
__all__ = ["NonStandardBehaviorHandler", "EmptyCommandHandler", "Printer", "DescriptionMessageGenerator", "HandlerFunc"]
|
||||
|
||||
from typing import ParamSpec, Protocol, TypeVar
|
||||
from typing import Any, ParamSpec, Protocol, TypeVar
|
||||
from argenta.response import Response
|
||||
|
||||
T = TypeVar("T", contravariant=True)
|
||||
@@ -28,5 +28,5 @@ class DescriptionMessageGenerator(Protocol):
|
||||
|
||||
|
||||
class HandlerFunc(Protocol):
|
||||
def __call__(self, response: Response) -> None:
|
||||
def __call__(self, response: Response, /, *args: Any, **kwargs: Any) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -61,6 +61,9 @@ linters = [
|
||||
{ name = "ruff" },
|
||||
{ name = "wemake-python-styleguide" },
|
||||
]
|
||||
metrics = [
|
||||
{ name = "py-cpuinfo" },
|
||||
]
|
||||
tests = [
|
||||
{ name = "pyfakefs" },
|
||||
{ name = "pytest" },
|
||||
@@ -92,6 +95,7 @@ linters = [
|
||||
{ name = "ruff", specifier = ">=0.12.12" },
|
||||
{ name = "wemake-python-styleguide", specifier = ">=0.17.0" },
|
||||
]
|
||||
metrics = [{ name = "py-cpuinfo", specifier = ">=9.0.0" }]
|
||||
tests = [
|
||||
{ name = "pyfakefs", specifier = ">=5.5.0" },
|
||||
{ name = "pytest", specifier = ">=8.3.2" },
|
||||
@@ -589,6 +593,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "py-cpuinfo"
|
||||
version = "9.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716, upload-time = "2022-10-25T20:38:06.303Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335, upload-time = "2022-10-25T20:38:27.636Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycodestyle"
|
||||
version = "2.14.0"
|
||||
|
||||
Reference in New Issue
Block a user