mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 18:15:28 +03:00
ruff format
This commit is contained in:
+6
-6
@@ -1,18 +1,18 @@
|
|||||||
from argenta import App, Orchestrator, Command
|
from argenta import App, Command, Orchestrator
|
||||||
from argenta.app import DynamicDividingLine
|
|
||||||
from .handlers import router
|
from .handlers import router
|
||||||
|
|
||||||
|
app = App(initial_message="metrics", exit_command=Command("exit", aliases=["quit"]))
|
||||||
app = App(initial_message="metrics", exit_command=Command('exit', aliases=['quit']))
|
|
||||||
orchestrator = Orchestrator()
|
orchestrator = Orchestrator()
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
app.include_router(router)
|
app.include_router(router)
|
||||||
app.set_description_message_pattern(
|
app.set_description_message_pattern(
|
||||||
lambda command, description: f'[bold cyan]▸[/bold cyan] [bold white]{command}[/bold white] [dim]│[/dim] [yellow italic]{description}[/yellow italic]'
|
lambda command,
|
||||||
|
description: f"[bold cyan]▸[/bold cyan] [bold white]{command}[/bold white] [dim]│[/dim] [yellow italic]{description}[/yellow italic]"
|
||||||
)
|
)
|
||||||
orchestrator.run_repl(app)
|
# orchestrator.run_repl(app)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ class BenchmarksNotFound(Exception):
|
|||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"Benchmarks with type '{self.type_}' not found"
|
return f"Benchmarks with type '{self.type_}' not found"
|
||||||
|
|
||||||
|
|
||||||
class BenchmarksWithSameNameAlreadyExists(Exception):
|
class BenchmarksWithSameNameAlreadyExists(Exception):
|
||||||
def __init__(self, benchmark_name: str):
|
def __init__(self, benchmark_name: str):
|
||||||
self.benchmark_name = benchmark_name
|
self.benchmark_name = benchmark_name
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"Benchmarks with name '{self.benchmark_name}' already exists"
|
return f"Benchmarks with name '{self.benchmark_name}' already exists"
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
__all__ = [
|
__all__ = ["Benchmark", "Benchmarks", "BenchmarkResult", "BenchmarkGroupResult"]
|
||||||
"Benchmark",
|
|
||||||
"Benchmarks",
|
|
||||||
"BenchmarkResult",
|
|
||||||
"BenchmarkGroupResult"
|
|
||||||
]
|
|
||||||
|
|
||||||
|
import gc
|
||||||
import io
|
import io
|
||||||
|
import statistics
|
||||||
|
import time
|
||||||
from contextlib import redirect_stdout
|
from contextlib import redirect_stdout
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import time
|
|
||||||
import gc
|
|
||||||
import statistics
|
|
||||||
from typing import Callable, override
|
from typing import Callable, override
|
||||||
|
|
||||||
from .exceptions import BenchmarkNotFound, BenchmarksNotFound, BenchmarksWithSameNameAlreadyExists
|
from .exceptions import BenchmarkNotFound, BenchmarksNotFound, BenchmarksWithSameNameAlreadyExists
|
||||||
@@ -40,14 +35,7 @@ class BenchmarkGroupResult:
|
|||||||
|
|
||||||
|
|
||||||
class Benchmark:
|
class Benchmark:
|
||||||
def __init__(
|
def __init__(self, func: FuncForBenchmark, *, type_: str, name: str, description: str) -> None:
|
||||||
self,
|
|
||||||
func: FuncForBenchmark,
|
|
||||||
*,
|
|
||||||
type_: str,
|
|
||||||
name: str,
|
|
||||||
description: str
|
|
||||||
) -> None:
|
|
||||||
self.func = func
|
self.func = func
|
||||||
self.type_ = type_
|
self.type_ = type_
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -78,11 +66,11 @@ class Benchmark:
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f'Benchmark<{self.type_=}, {self.name=}, {self.description=}>'
|
return f"Benchmark<{self.type_=}, {self.name=}, {self.description=}>"
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f'benchmark {self.name} with type {self.type_}'
|
return f"benchmark {self.name} with type {self.type_}"
|
||||||
|
|
||||||
|
|
||||||
class Benchmarks:
|
class Benchmarks:
|
||||||
@@ -92,16 +80,14 @@ class Benchmarks:
|
|||||||
self._benchmarks_paired_by_name: dict[str, Benchmark] = {}
|
self._benchmarks_paired_by_name: dict[str, Benchmark] = {}
|
||||||
|
|
||||||
def register(
|
def register(
|
||||||
self,
|
self, type_: str, description: str = ""
|
||||||
type_: str,
|
|
||||||
description: str = ""
|
|
||||||
) -> Callable[[FuncForBenchmark], FuncForBenchmark]:
|
) -> Callable[[FuncForBenchmark], FuncForBenchmark]:
|
||||||
def decorator(func: FuncForBenchmark) -> FuncForBenchmark:
|
def decorator(func: FuncForBenchmark) -> FuncForBenchmark:
|
||||||
benchmark = Benchmark(
|
benchmark = Benchmark(
|
||||||
func,
|
func,
|
||||||
type_=type_,
|
type_=type_,
|
||||||
name=func.__name__,
|
name=func.__name__,
|
||||||
description=description or f'description for {func.__name__} with type {type_}',
|
description=description or f"description for {func.__name__} with type {type_}",
|
||||||
)
|
)
|
||||||
if self._benchmarks_paired_by_name.get(func.__name__):
|
if self._benchmarks_paired_by_name.get(func.__name__):
|
||||||
raise BenchmarksWithSameNameAlreadyExists(func.__name__)
|
raise BenchmarksWithSameNameAlreadyExists(func.__name__)
|
||||||
@@ -110,9 +96,12 @@ class Benchmarks:
|
|||||||
self._benchmarks.append(benchmark)
|
self._benchmarks.append(benchmark)
|
||||||
self._benchmarks_grouped_by_type.setdefault(type_, []).append(benchmark)
|
self._benchmarks_grouped_by_type.setdefault(type_, []).append(benchmark)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def run_benchmark_by_name(self, name: str, iterations: int = 100, is_gc_disables: bool = False) -> BenchmarkResult:
|
def run_benchmark_by_name(
|
||||||
|
self, name: str, iterations: int = 100, is_gc_disables: bool = False
|
||||||
|
) -> BenchmarkResult:
|
||||||
benchmark = self.get_benchmark_by_name(name)
|
benchmark = self.get_benchmark_by_name(name)
|
||||||
if not benchmark:
|
if not benchmark:
|
||||||
raise BenchmarkNotFound(name)
|
raise BenchmarkNotFound(name)
|
||||||
@@ -130,28 +119,34 @@ class Benchmarks:
|
|||||||
is_gc_disabled=is_gc_disables,
|
is_gc_disabled=is_gc_disables,
|
||||||
avg_time=avg,
|
avg_time=avg,
|
||||||
median_time=median,
|
median_time=median,
|
||||||
std_dev=std_dev
|
std_dev=std_dev,
|
||||||
)
|
)
|
||||||
|
|
||||||
def run_benchmarks_by_type(self, type_: str, iterations: int = 100, is_gc_disabled: bool = False) -> BenchmarkGroupResult:
|
def run_benchmarks_by_type(
|
||||||
|
self, type_: str, iterations: int = 100, is_gc_disabled: bool = False
|
||||||
|
) -> BenchmarkGroupResult:
|
||||||
benchmarks = self.get_benchmarks_by_type(type_)
|
benchmarks = self.get_benchmarks_by_type(type_)
|
||||||
if not benchmarks:
|
if not benchmarks:
|
||||||
raise BenchmarksNotFound(type_)
|
raise BenchmarksNotFound(type_)
|
||||||
benchmark_results: list[BenchmarkResult] = []
|
benchmark_results: list[BenchmarkResult] = []
|
||||||
|
|
||||||
for benchmark in benchmarks:
|
for benchmark in benchmarks:
|
||||||
benchmark_results.append(self.run_benchmark_by_name(benchmark.name, iterations, is_gc_disabled))
|
benchmark_results.append(
|
||||||
|
self.run_benchmark_by_name(benchmark.name, iterations, is_gc_disabled)
|
||||||
|
)
|
||||||
|
|
||||||
return BenchmarkGroupResult(
|
return BenchmarkGroupResult(
|
||||||
type_=type_,
|
type_=type_,
|
||||||
iterations=iterations,
|
iterations=iterations,
|
||||||
is_gc_disabled=is_gc_disabled,
|
is_gc_disabled=is_gc_disabled,
|
||||||
benchmark_results=benchmark_results
|
benchmark_results=benchmark_results,
|
||||||
)
|
)
|
||||||
|
|
||||||
def run_benchmarks_grouped_by_type(self, iterations: int = 100, is_gc_disabled: bool = False) -> list[BenchmarkGroupResult]:
|
def run_benchmarks_grouped_by_type(
|
||||||
|
self, iterations: int = 100, is_gc_disabled: bool = False
|
||||||
|
) -> list[BenchmarkGroupResult]:
|
||||||
results: list[BenchmarkGroupResult] = []
|
results: list[BenchmarkGroupResult] = []
|
||||||
for type_, benchmarks in self._benchmarks_grouped_by_type.items():
|
for type_, _ in self._benchmarks_grouped_by_type.items():
|
||||||
results.append(self.run_benchmarks_by_type(type_, iterations, is_gc_disabled))
|
results.append(self.run_benchmarks_by_type(type_, iterations, is_gc_disabled))
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ __all__ = [
|
|||||||
"benchmark_command_with_flags",
|
"benchmark_command_with_flags",
|
||||||
"benchmark_many_commands",
|
"benchmark_many_commands",
|
||||||
"benchmark_command_with_many_flags",
|
"benchmark_command_with_many_flags",
|
||||||
"benchmark_extreme_router"
|
"benchmark_extreme_router",
|
||||||
]
|
]
|
||||||
|
|
||||||
from argenta.command.models import Command, InputCommand
|
|
||||||
from argenta.command import Flag, Flags
|
from argenta.command import Flag, Flags
|
||||||
|
from argenta.command.models import Command, InputCommand
|
||||||
from argenta.response import Response
|
from argenta.response import Response
|
||||||
from argenta.router import Router
|
from argenta.router import Router
|
||||||
|
|
||||||
@@ -18,11 +18,11 @@ from .entity import benchmarks
|
|||||||
def benchmark_simple_command() -> None:
|
def benchmark_simple_command() -> None:
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command('test'))
|
@router.command(Command("test"))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
input_cmd = InputCommand.parse('test')
|
input_cmd = InputCommand.parse("test")
|
||||||
router.finds_appropriate_handler(input_cmd)
|
router.finds_appropriate_handler(input_cmd)
|
||||||
|
|
||||||
|
|
||||||
@@ -30,11 +30,11 @@ def benchmark_simple_command() -> None:
|
|||||||
def benchmark_command_with_flags() -> None:
|
def benchmark_command_with_flags() -> None:
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command('test', flags=Flags([Flag('a'), Flag('b'), Flag('c')])))
|
@router.command(Command("test", flags=Flags([Flag("a"), Flag("b"), Flag("c")])))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
input_cmd = InputCommand.parse('test -a -b -c')
|
input_cmd = InputCommand.parse("test -a -b -c")
|
||||||
router.finds_appropriate_handler(input_cmd)
|
router.finds_appropriate_handler(input_cmd)
|
||||||
|
|
||||||
|
|
||||||
@@ -43,38 +43,43 @@ def benchmark_many_commands() -> None:
|
|||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
for i in range(50):
|
for i in range(50):
|
||||||
@router.command(Command(f'cmd{i}'))
|
|
||||||
|
@router.command(Command(f"cmd{i}"))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
input_cmd = InputCommand.parse('cmd25')
|
input_cmd = InputCommand.parse("cmd25")
|
||||||
router.finds_appropriate_handler(input_cmd)
|
router.finds_appropriate_handler(input_cmd)
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="finds_appropriate_handler", description="Command with many flags (20 flags)")
|
@benchmarks.register(
|
||||||
|
type_="finds_appropriate_handler", description="Command with many flags (20 flags)"
|
||||||
|
)
|
||||||
def benchmark_command_with_many_flags() -> None:
|
def benchmark_command_with_many_flags() -> None:
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
flags = Flags([Flag(f'flag{i}') for i in range(20)])
|
flags = Flags([Flag(f"flag{i}") for i in range(20)])
|
||||||
|
|
||||||
@router.command(Command('test', flags=flags))
|
@router.command(Command("test", flags=flags))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
input_cmd = InputCommand.parse('test ' + ' '.join(f'-flag{i}' for i in range(10)))
|
input_cmd = InputCommand.parse("test " + " ".join(f"-flag{i}" for i in range(10)))
|
||||||
router.finds_appropriate_handler(input_cmd)
|
router.finds_appropriate_handler(input_cmd)
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="finds_appropriate_handler", description="Extreme (100 commands, 10 flags each)")
|
@benchmarks.register(
|
||||||
|
type_="finds_appropriate_handler", description="Extreme (100 commands, 10 flags each)"
|
||||||
|
)
|
||||||
def benchmark_extreme_router() -> None:
|
def benchmark_extreme_router() -> None:
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
flags = Flags([Flag(f'f{i}_{j}') for j in range(10)])
|
flags = Flags([Flag(f"f{i}_{j}") for j in range(10)])
|
||||||
|
|
||||||
@router.command(Command(f'cmd{i}', flags=flags))
|
@router.command(Command(f"cmd{i}", flags=flags))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
input_cmd = InputCommand.parse('cmd50 -f50_0 -f50_1 -f50_2')
|
input_cmd = InputCommand.parse("cmd50 -f50_0 -f50_1 -f50_2")
|
||||||
router.finds_appropriate_handler(input_cmd)
|
router.finds_appropriate_handler(input_cmd)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ __all__ = [
|
|||||||
"benchmark_validate_regex_complex",
|
"benchmark_validate_regex_complex",
|
||||||
"benchmark_validate_multiple_flags_10",
|
"benchmark_validate_multiple_flags_10",
|
||||||
"benchmark_validate_multiple_flags_50",
|
"benchmark_validate_multiple_flags_50",
|
||||||
"benchmark_validate_extreme_100_flags"
|
"benchmark_validate_extreme_100_flags",
|
||||||
]
|
]
|
||||||
|
|
||||||
import re
|
import re
|
||||||
@@ -58,14 +58,8 @@ def benchmark_validate_regex_complex() -> None:
|
|||||||
|
|
||||||
@benchmarks.register(type_="flag_validation", description="Multiple flags validation (10 flags)")
|
@benchmarks.register(type_="flag_validation", description="Multiple flags validation (10 flags)")
|
||||||
def benchmark_validate_multiple_flags_10() -> None:
|
def benchmark_validate_multiple_flags_10() -> None:
|
||||||
flags = [
|
flags = [Flag(f"flag{i}", possible_values=PossibleValues.ALL) for i in range(10)]
|
||||||
Flag(f"flag{i}", possible_values=PossibleValues.ALL)
|
input_flags = [InputFlag(f"flag{i}", input_value=f"value{i}") for i in range(10)]
|
||||||
for i in range(10)
|
|
||||||
]
|
|
||||||
input_flags = [
|
|
||||||
InputFlag(f"flag{i}", input_value=f"value{i}")
|
|
||||||
for i in range(10)
|
|
||||||
]
|
|
||||||
|
|
||||||
for flag, input_flag in zip(flags, input_flags):
|
for flag, input_flag in zip(flags, input_flags):
|
||||||
flag.validate_input_flag_value(input_flag.input_value)
|
flag.validate_input_flag_value(input_flag.input_value)
|
||||||
@@ -73,30 +67,20 @@ def benchmark_validate_multiple_flags_10() -> None:
|
|||||||
|
|
||||||
@benchmarks.register(type_="flag_validation", description="Multiple flags validation (50 flags)")
|
@benchmarks.register(type_="flag_validation", description="Multiple flags validation (50 flags)")
|
||||||
def benchmark_validate_multiple_flags_50() -> None:
|
def benchmark_validate_multiple_flags_50() -> None:
|
||||||
flags = [
|
flags = [Flag(f"flag{i}", possible_values=PossibleValues.ALL) for i in range(50)]
|
||||||
Flag(f"flag{i}", possible_values=PossibleValues.ALL)
|
input_flags = [InputFlag(f"flag{i}", input_value=f"value{i}") for i in range(50)]
|
||||||
for i in range(50)
|
|
||||||
]
|
|
||||||
input_flags = [
|
|
||||||
InputFlag(f"flag{i}", input_value=f"value{i}")
|
|
||||||
for i in range(50)
|
|
||||||
]
|
|
||||||
|
|
||||||
for flag, input_flag in zip(flags, input_flags):
|
for flag, input_flag in zip(flags, input_flags):
|
||||||
flag.validate_input_flag_value(input_flag.input_value)
|
flag.validate_input_flag_value(input_flag.input_value)
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="flag_validation", description="Extreme (100 flags with regex validation)")
|
@benchmarks.register(
|
||||||
|
type_="flag_validation", description="Extreme (100 flags with regex validation)"
|
||||||
|
)
|
||||||
def benchmark_validate_extreme_100_flags() -> None:
|
def benchmark_validate_extreme_100_flags() -> None:
|
||||||
pattern = re.compile(r"^[a-zA-Z0-9_-]+$")
|
pattern = re.compile(r"^[a-zA-Z0-9_-]+$")
|
||||||
flags = [
|
flags = [Flag(f"flag{i}", possible_values=pattern) for i in range(100)]
|
||||||
Flag(f"flag{i}", possible_values=pattern)
|
input_flags = [InputFlag(f"flag{i}", input_value=f"valid_value_{i}") for i in range(100)]
|
||||||
for i in range(100)
|
|
||||||
]
|
|
||||||
input_flags = [
|
|
||||||
InputFlag(f"flag{i}", input_value=f"valid_value_{i}")
|
|
||||||
for i in range(100)
|
|
||||||
]
|
|
||||||
|
|
||||||
for flag, input_flag in zip(flags, input_flags):
|
for flag, input_flag in zip(flags, input_flags):
|
||||||
flag.validate_input_flag_value(input_flag.input_value)
|
flag.validate_input_flag_value(input_flag.input_value)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ __all__ = [
|
|||||||
"benchmark_command_with_mixed_prefixes",
|
"benchmark_command_with_mixed_prefixes",
|
||||||
"benchmark_command_with_long_values",
|
"benchmark_command_with_long_values",
|
||||||
"benchmark_command_with_quoted_values",
|
"benchmark_command_with_quoted_values",
|
||||||
"benchmark_extreme_many_flags"
|
"benchmark_extreme_many_flags",
|
||||||
]
|
]
|
||||||
|
|
||||||
from argenta.command.models import InputCommand
|
from argenta.command.models import InputCommand
|
||||||
@@ -23,12 +23,16 @@ def benchmark_command_with_few_flags() -> None:
|
|||||||
InputCommand.parse("start -a -b -c")
|
InputCommand.parse("start -a -b -c")
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="input_command_parse", description="Command with flags and values (5 flags)")
|
@benchmarks.register(
|
||||||
|
type_="input_command_parse", description="Command with flags and values (5 flags)"
|
||||||
|
)
|
||||||
def benchmark_command_with_flags_and_values() -> None:
|
def benchmark_command_with_flags_and_values() -> None:
|
||||||
InputCommand.parse("start --host localhost --port 8080 --debug --verbose -c config.json")
|
InputCommand.parse("start --host localhost --port 8080 --debug --verbose -c config.json")
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="input_command_parse", description="Command with mixed prefixes (-, --, ---)")
|
@benchmarks.register(
|
||||||
|
type_="input_command_parse", description="Command with mixed prefixes (-, --, ---)"
|
||||||
|
)
|
||||||
def benchmark_command_with_mixed_prefixes() -> None:
|
def benchmark_command_with_mixed_prefixes() -> None:
|
||||||
InputCommand.parse("cmd -a --bb ---ccc -d value --ee value2 ---fff value3")
|
InputCommand.parse("cmd -a --bb ---ccc -d value --ee value2 ---fff value3")
|
||||||
|
|
||||||
@@ -40,7 +44,9 @@ def benchmark_command_with_long_values() -> None:
|
|||||||
InputCommand.parse(cmd)
|
InputCommand.parse(cmd)
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="input_command_parse", description="Command with quoted values (5 flags)")
|
@benchmarks.register(
|
||||||
|
type_="input_command_parse", description="Command with quoted values (5 flags)"
|
||||||
|
)
|
||||||
def benchmark_command_with_quoted_values() -> None:
|
def benchmark_command_with_quoted_values() -> None:
|
||||||
InputCommand.parse("cmd --text 'hello world' --path '/usr/local/bin' --msg \"test message\"")
|
InputCommand.parse("cmd --text 'hello world' --path '/usr/local/bin' --msg \"test message\"")
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ __all__ = [
|
|||||||
"benchmark_many_commands_most_similar",
|
"benchmark_many_commands_most_similar",
|
||||||
"benchmark_many_aliases",
|
"benchmark_many_aliases",
|
||||||
"benchmark_partial_match",
|
"benchmark_partial_match",
|
||||||
"benchmark_extreme_commands"
|
"benchmark_extreme_commands",
|
||||||
]
|
]
|
||||||
|
|
||||||
from argenta import App
|
from argenta import App
|
||||||
@@ -19,9 +19,11 @@ def setup_app_with_commands(command_count: int, aliases_per_command: int = 0) ->
|
|||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
for i in range(command_count):
|
for i in range(command_count):
|
||||||
aliases = {f'alias{i}_{j}' for j in range(aliases_per_command)} if aliases_per_command else set()
|
aliases = (
|
||||||
|
{f"alias{i}_{j}" for j in range(aliases_per_command)} if aliases_per_command else set()
|
||||||
|
)
|
||||||
|
|
||||||
@router.command(Command(f'command{i}', aliases=aliases))
|
@router.command(Command(f"command{i}", aliases=aliases))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -29,31 +31,41 @@ def setup_app_with_commands(command_count: int, aliases_per_command: int = 0) ->
|
|||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="most_similar_command", description="Few commands (10 commands, no match)")
|
@benchmarks.register(
|
||||||
|
type_="most_similar_command", description="Few commands (10 commands, no match)"
|
||||||
|
)
|
||||||
def benchmark_few_commands() -> None:
|
def benchmark_few_commands() -> None:
|
||||||
app = setup_app_with_commands(10)
|
app = setup_app_with_commands(10)
|
||||||
app._most_similar_command("unknown")
|
app._most_similar_command("unknown")
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="most_similar_command", description="Many commands (50 commands, no match)")
|
@benchmarks.register(
|
||||||
|
type_="most_similar_command", description="Many commands (50 commands, no match)"
|
||||||
|
)
|
||||||
def benchmark_many_commands_most_similar() -> None:
|
def benchmark_many_commands_most_similar() -> None:
|
||||||
app = setup_app_with_commands(50)
|
app = setup_app_with_commands(50)
|
||||||
app._most_similar_command("unknown")
|
app._most_similar_command("unknown")
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="most_similar_command", description="Many aliases (20 commands, 10 aliases each)")
|
@benchmarks.register(
|
||||||
|
type_="most_similar_command", description="Many aliases (20 commands, 10 aliases each)"
|
||||||
|
)
|
||||||
def benchmark_many_aliases() -> None:
|
def benchmark_many_aliases() -> None:
|
||||||
app = setup_app_with_commands(20, aliases_per_command=10)
|
app = setup_app_with_commands(20, aliases_per_command=10)
|
||||||
app._most_similar_command("unknown")
|
app._most_similar_command("unknown")
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="most_similar_command", description="Partial match (50 commands, prefix match)")
|
@benchmarks.register(
|
||||||
|
type_="most_similar_command", description="Partial match (50 commands, prefix match)"
|
||||||
|
)
|
||||||
def benchmark_partial_match() -> None:
|
def benchmark_partial_match() -> None:
|
||||||
app = setup_app_with_commands(50)
|
app = setup_app_with_commands(50)
|
||||||
app._most_similar_command("comm")
|
app._most_similar_command("comm")
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="most_similar_command", description="Extreme (100 commands, 20 aliases each)")
|
@benchmarks.register(
|
||||||
|
type_="most_similar_command", description="Extreme (100 commands, 20 aliases each)"
|
||||||
|
)
|
||||||
def benchmark_extreme_commands() -> None:
|
def benchmark_extreme_commands() -> None:
|
||||||
app = setup_app_with_commands(100, aliases_per_command=20)
|
app = setup_app_with_commands(100, aliases_per_command=20)
|
||||||
app._most_similar_command("comm")
|
app._most_similar_command("comm")
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ __all__ = [
|
|||||||
"benchmark_with_many_aliases",
|
"benchmark_with_many_aliases",
|
||||||
"benchmark_few_aliases",
|
"benchmark_few_aliases",
|
||||||
"benchmark_extreme_aliases",
|
"benchmark_extreme_aliases",
|
||||||
"benchmark_very_many_aliases"
|
"benchmark_very_many_aliases",
|
||||||
]
|
]
|
||||||
|
|
||||||
from argenta import App
|
from argenta import App
|
||||||
@@ -19,15 +19,15 @@ def benchmark_no_aliases() -> None:
|
|||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command('command1'))
|
@router.command(Command("command1"))
|
||||||
def handler1(_res: Response) -> None:
|
def handler1(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command2'))
|
@router.command(Command("command2"))
|
||||||
def handler2(_res: Response) -> None:
|
def handler2(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command3'))
|
@router.command(Command("command3"))
|
||||||
def handler3(_res: Response) -> None:
|
def handler3(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -40,15 +40,15 @@ def benchmark_few_aliases() -> None:
|
|||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command('command1', aliases={'c1', 'cmd1'}))
|
@router.command(Command("command1", aliases={"c1", "cmd1"}))
|
||||||
def handler1(_res: Response) -> None:
|
def handler1(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command2', aliases={'c2', 'cmd2'}))
|
@router.command(Command("command2", aliases={"c2", "cmd2"}))
|
||||||
def handler2(_res: Response) -> None:
|
def handler2(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command3', aliases={'c3', 'cmd3'}))
|
@router.command(Command("command3", aliases={"c3", "cmd3"}))
|
||||||
def handler3(_res: Response) -> None:
|
def handler3(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -61,15 +61,15 @@ def benchmark_with_many_aliases() -> None:
|
|||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command('command1', aliases={'c1', 'cmd1', 'com1', 'first', 'one'}))
|
@router.command(Command("command1", aliases={"c1", "cmd1", "com1", "first", "one"}))
|
||||||
def handler1(_res: Response) -> None:
|
def handler1(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command2', aliases={'c2', 'cmd2', 'com2', 'second', 'two'}))
|
@router.command(Command("command2", aliases={"c2", "cmd2", "com2", "second", "two"}))
|
||||||
def handler2(_res: Response) -> None:
|
def handler2(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command3', aliases={'c3', 'cmd3', 'com3', 'third', 'three'}))
|
@router.command(Command("command3", aliases={"c3", "cmd3", "com3", "third", "three"}))
|
||||||
def handler3(_res: Response) -> None:
|
def handler3(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -82,15 +82,15 @@ def benchmark_very_many_aliases() -> None:
|
|||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command('command1', aliases={f'alias1_{i}' for i in range(20)}))
|
@router.command(Command("command1", aliases={f"alias1_{i}" for i in range(20)}))
|
||||||
def handler1(_res: Response) -> None:
|
def handler1(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command2', aliases={f'alias2_{i}' for i in range(20)}))
|
@router.command(Command("command2", aliases={f"alias2_{i}" for i in range(20)}))
|
||||||
def handler2(_res: Response) -> None:
|
def handler2(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command3', aliases={f'alias3_{i}' for i in range(20)}))
|
@router.command(Command("command3", aliases={f"alias3_{i}" for i in range(20)}))
|
||||||
def handler3(_res: Response) -> None:
|
def handler3(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -103,15 +103,15 @@ def benchmark_extreme_aliases() -> None:
|
|||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command('command1', aliases={f'alias1_{i}' for i in range(100)}))
|
@router.command(Command("command1", aliases={f"alias1_{i}" for i in range(100)}))
|
||||||
def handler1(_res: Response) -> None:
|
def handler1(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command2', aliases={f'alias2_{i}' for i in range(100)}))
|
@router.command(Command("command2", aliases={f"alias2_{i}" for i in range(100)}))
|
||||||
def handler2(_res: Response) -> None:
|
def handler2(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@router.command(Command('command3', aliases={f'alias3_{i}' for i in range(100)}))
|
@router.command(Command("command3", aliases={f"alias3_{i}" for i in range(100)}))
|
||||||
def handler3(_res: Response) -> None:
|
def handler3(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ __all__ = [
|
|||||||
"benchmark_many_routers",
|
"benchmark_many_routers",
|
||||||
"benchmark_many_commands_per_router",
|
"benchmark_many_commands_per_router",
|
||||||
"benchmark_many_aliases_per_command",
|
"benchmark_many_aliases_per_command",
|
||||||
"benchmark_extreme_routers"
|
"benchmark_extreme_routers",
|
||||||
]
|
]
|
||||||
|
|
||||||
from argenta import App
|
from argenta import App
|
||||||
@@ -14,14 +14,17 @@ from argenta.router import Router
|
|||||||
from .entity import benchmarks
|
from .entity import benchmarks
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="validate_routers_for_collisions", description="With few routers (3 routers, 1 command each)")
|
@benchmarks.register(
|
||||||
|
type_="validate_routers_for_collisions",
|
||||||
|
description="With few routers (3 routers, 1 command each)",
|
||||||
|
)
|
||||||
def benchmark_few_routers() -> None:
|
def benchmark_few_routers() -> None:
|
||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
|
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command(f'cmd{i}'))
|
@router.command(Command(f"cmd{i}"))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -31,14 +34,17 @@ def benchmark_few_routers() -> None:
|
|||||||
app._validate_routers_for_collisions()
|
app._validate_routers_for_collisions()
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="validate_routers_for_collisions", description="With many routers (10 routers, 1 command each)")
|
@benchmarks.register(
|
||||||
|
type_="validate_routers_for_collisions",
|
||||||
|
description="With many routers (10 routers, 1 command each)",
|
||||||
|
)
|
||||||
def benchmark_many_routers() -> None:
|
def benchmark_many_routers() -> None:
|
||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
|
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@router.command(Command(f'cmd{i}'))
|
@router.command(Command(f"cmd{i}"))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -48,7 +54,10 @@ def benchmark_many_routers() -> None:
|
|||||||
app._validate_routers_for_collisions()
|
app._validate_routers_for_collisions()
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="validate_routers_for_collisions", description="With many commands per router (3 routers, 10 commands each)")
|
@benchmarks.register(
|
||||||
|
type_="validate_routers_for_collisions",
|
||||||
|
description="With many commands per router (3 routers, 10 commands each)",
|
||||||
|
)
|
||||||
def benchmark_many_commands_per_router() -> None:
|
def benchmark_many_commands_per_router() -> None:
|
||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
|
|
||||||
@@ -56,7 +65,8 @@ def benchmark_many_commands_per_router() -> None:
|
|||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
for j in range(10):
|
for j in range(10):
|
||||||
@router.command(Command(f'cmd{i}_{j}'))
|
|
||||||
|
@router.command(Command(f"cmd{i}_{j}"))
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -66,7 +76,10 @@ def benchmark_many_commands_per_router() -> None:
|
|||||||
app._validate_routers_for_collisions()
|
app._validate_routers_for_collisions()
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="validate_routers_for_collisions", description="With many aliases (3 routers, 5 commands, 10 aliases each)")
|
@benchmarks.register(
|
||||||
|
type_="validate_routers_for_collisions",
|
||||||
|
description="With many aliases (3 routers, 5 commands, 10 aliases each)",
|
||||||
|
)
|
||||||
def benchmark_many_aliases_per_command() -> None:
|
def benchmark_many_aliases_per_command() -> None:
|
||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
|
|
||||||
@@ -74,7 +87,10 @@ def benchmark_many_aliases_per_command() -> None:
|
|||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
for j in range(5):
|
for j in range(5):
|
||||||
@router.command(Command(f'cmd{i}_{j}', aliases={f'alias{i}_{j}_{k}' for k in range(10)}))
|
|
||||||
|
@router.command(
|
||||||
|
Command(f"cmd{i}_{j}", aliases={f"alias{i}_{j}_{k}" for k in range(10)})
|
||||||
|
)
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -84,7 +100,10 @@ def benchmark_many_aliases_per_command() -> None:
|
|||||||
app._validate_routers_for_collisions()
|
app._validate_routers_for_collisions()
|
||||||
|
|
||||||
|
|
||||||
@benchmarks.register(type_="validate_routers_for_collisions", description="Extreme (20 routers, 10 commands, 20 aliases each)")
|
@benchmarks.register(
|
||||||
|
type_="validate_routers_for_collisions",
|
||||||
|
description="Extreme (20 routers, 10 commands, 20 aliases each)",
|
||||||
|
)
|
||||||
def benchmark_extreme_routers() -> None:
|
def benchmark_extreme_routers() -> None:
|
||||||
app = App(override_system_messages=True)
|
app = App(override_system_messages=True)
|
||||||
|
|
||||||
@@ -92,7 +111,10 @@ def benchmark_extreme_routers() -> None:
|
|||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
for j in range(10):
|
for j in range(10):
|
||||||
@router.command(Command(f'cmd{i}_{j}', aliases={f'alias{i}_{j}_{k}' for k in range(20)}))
|
|
||||||
|
@router.command(
|
||||||
|
Command(f"cmd{i}_{j}", aliases={f"alias{i}_{j}_{k}" for k in range(20)})
|
||||||
|
)
|
||||||
def handler(_res: Response) -> None:
|
def handler(_res: Response) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
+56
-33
@@ -5,17 +5,18 @@ from pathlib import Path
|
|||||||
|
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
from argenta.command import Flag, PossibleValues, Flags
|
from argenta.command import Flag, Flags, PossibleValues
|
||||||
from argenta.command.flag import ValidationStatus
|
from argenta.command.flag import ValidationStatus
|
||||||
from argenta.command.models import Command
|
from argenta.command.models import Command
|
||||||
from argenta.response import Response
|
from argenta.response import Response
|
||||||
from argenta.router import Router
|
from argenta.router import Router
|
||||||
|
|
||||||
from .benchmarks.core.models import BenchmarkGroupResult
|
from .benchmarks.core.models import BenchmarkGroupResult
|
||||||
from .benchmarks.entity import benchmarks as registered_benchmarks
|
from .benchmarks.entity import benchmarks as registered_benchmarks
|
||||||
from .services.report_table_generator import ReportTableGenerator
|
|
||||||
from .services.system_info_reader import get_system_info
|
|
||||||
from .services.diagram_generator import DiagramGenerator
|
from .services.diagram_generator import DiagramGenerator
|
||||||
from .services.release_generator import ReleaseGenerator
|
from .services.release_generator import ReleaseGenerator
|
||||||
|
from .services.report_table_generator import ReportTableGenerator
|
||||||
|
from .services.system_info_reader import get_system_info
|
||||||
|
|
||||||
console = Console()
|
console = Console()
|
||||||
router = Router(title="Metrics commands:", disable_redirect_stdout=True)
|
router = Router(title="Metrics commands:", disable_redirect_stdout=True)
|
||||||
@@ -27,22 +28,30 @@ POSITIVE_INTEGER_PATTERN = re.compile(r"^[1-9]\d*$")
|
|||||||
Command(
|
Command(
|
||||||
"run-all",
|
"run-all",
|
||||||
description="Print all benchmarks results",
|
description="Print all benchmarks results",
|
||||||
flags=Flags([
|
flags=Flags(
|
||||||
Flag('without-gc', possible_values=PossibleValues.NEITHER),
|
[
|
||||||
Flag('without-system-info', possible_values=PossibleValues.NEITHER)
|
Flag("without-gc", possible_values=PossibleValues.NEITHER),
|
||||||
])
|
Flag("without-system-info", possible_values=PossibleValues.NEITHER),
|
||||||
|
]
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def all_print_handler(response: Response) -> None:
|
def all_print_handler(response: Response) -> None:
|
||||||
report_generator = ReportTableGenerator(get_system_info())
|
report_generator = ReportTableGenerator(get_system_info())
|
||||||
|
|
||||||
without_system_info = response.input_flags.get_flag_by_name("without-system-info", with_status=ValidationStatus.VALID)
|
without_system_info = response.input_flags.get_flag_by_name(
|
||||||
|
"without-system-info", with_status=ValidationStatus.VALID
|
||||||
|
)
|
||||||
if not without_system_info:
|
if not without_system_info:
|
||||||
console.print(report_generator.generate_system_info_header())
|
console.print(report_generator.generate_system_info_header())
|
||||||
console.print(report_generator.generate_system_info_table())
|
console.print(report_generator.generate_system_info_table())
|
||||||
|
|
||||||
is_gc_disabled = response.input_flags.get_flag_by_name("without-gc", with_status=ValidationStatus.VALID)
|
is_gc_disabled = response.input_flags.get_flag_by_name(
|
||||||
type_grouped_benchmarks: list[BenchmarkGroupResult] = registered_benchmarks.run_benchmarks_grouped_by_type(is_gc_disabled=bool(is_gc_disabled))
|
"without-gc", with_status=ValidationStatus.VALID
|
||||||
|
)
|
||||||
|
type_grouped_benchmarks: list[BenchmarkGroupResult] = (
|
||||||
|
registered_benchmarks.run_benchmarks_grouped_by_type(is_gc_disabled=bool(is_gc_disabled))
|
||||||
|
)
|
||||||
|
|
||||||
for benchmark_group_result in type_grouped_benchmarks:
|
for benchmark_group_result in type_grouped_benchmarks:
|
||||||
console.print(report_generator.generate_benchmark_table_header(benchmark_group_result))
|
console.print(report_generator.generate_benchmark_table_header(benchmark_group_result))
|
||||||
@@ -67,11 +76,13 @@ def list_types_handler(_: Response) -> None:
|
|||||||
Command(
|
Command(
|
||||||
"run-type",
|
"run-type",
|
||||||
description="Run benchmarks by specific type",
|
description="Run benchmarks by specific type",
|
||||||
flags=Flags([
|
flags=Flags(
|
||||||
Flag('type', possible_values=registered_benchmarks.get_types()),
|
[
|
||||||
Flag('without-gc', possible_values=PossibleValues.NEITHER),
|
Flag("type", possible_values=registered_benchmarks.get_types()),
|
||||||
Flag('without-system-info', possible_values=PossibleValues.NEITHER)
|
Flag("without-gc", possible_values=PossibleValues.NEITHER),
|
||||||
])
|
Flag("without-system-info", possible_values=PossibleValues.NEITHER),
|
||||||
|
]
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def run_type_handler(response: Response) -> None:
|
def run_type_handler(response: Response) -> None:
|
||||||
@@ -94,13 +105,19 @@ def run_type_handler(response: Response) -> None:
|
|||||||
|
|
||||||
report_generator = ReportTableGenerator(get_system_info())
|
report_generator = ReportTableGenerator(get_system_info())
|
||||||
|
|
||||||
without_system_info = response.input_flags.get_flag_by_name("without-system-info", with_status=ValidationStatus.VALID)
|
without_system_info = response.input_flags.get_flag_by_name(
|
||||||
|
"without-system-info", with_status=ValidationStatus.VALID
|
||||||
|
)
|
||||||
if not without_system_info:
|
if not without_system_info:
|
||||||
console.print(report_generator.generate_system_info_header())
|
console.print(report_generator.generate_system_info_header())
|
||||||
console.print(report_generator.generate_system_info_table())
|
console.print(report_generator.generate_system_info_table())
|
||||||
|
|
||||||
is_gc_disabled = response.input_flags.get_flag_by_name("without-gc", with_status=ValidationStatus.VALID, default=False)
|
is_gc_disabled = response.input_flags.get_flag_by_name(
|
||||||
benchmark_group_result = registered_benchmarks.run_benchmarks_by_type(benchmark_type, is_gc_disabled=bool(is_gc_disabled))
|
"without-gc", with_status=ValidationStatus.VALID, default=False
|
||||||
|
)
|
||||||
|
benchmark_group_result = registered_benchmarks.run_benchmarks_by_type(
|
||||||
|
benchmark_type, is_gc_disabled=bool(is_gc_disabled)
|
||||||
|
)
|
||||||
|
|
||||||
console.print(report_generator.generate_benchmark_table_header(benchmark_group_result))
|
console.print(report_generator.generate_benchmark_table_header(benchmark_group_result))
|
||||||
console.print(report_generator.generate_benchmark_report_table(benchmark_group_result))
|
console.print(report_generator.generate_benchmark_report_table(benchmark_group_result))
|
||||||
@@ -113,22 +130,21 @@ def release_generate_handler(_: Response) -> None:
|
|||||||
console.print(f"[cyan]Generating release report for version:[/cyan] [bold]{lib_version}[/bold]")
|
console.print(f"[cyan]Generating release report for version:[/cyan] [bold]{lib_version}[/bold]")
|
||||||
console.print("[dim]Running benchmarks (1000 iterations, GC disabled)...[/dim]\n")
|
console.print("[dim]Running benchmarks (1000 iterations, GC disabled)...[/dim]\n")
|
||||||
|
|
||||||
type_grouped_benchmarks: list[BenchmarkGroupResult] = registered_benchmarks.run_benchmarks_grouped_by_type(
|
type_grouped_benchmarks: list[BenchmarkGroupResult] = (
|
||||||
iterations=1000,
|
registered_benchmarks.run_benchmarks_grouped_by_type(iterations=1000, is_gc_disabled=True)
|
||||||
is_gc_disabled=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
release_generator = ReleaseGenerator(lib_version)
|
release_generator = ReleaseGenerator(lib_version)
|
||||||
output_dir = release_generator.generate_release(type_grouped_benchmarks)
|
output_dir = release_generator.generate_release(type_grouped_benchmarks)
|
||||||
|
|
||||||
console.print(f"[green]✓[/green] Benchmarks completed. Generating release report...\n")
|
console.print("[green]✓[/green] Benchmarks completed. Generating release report...\n")
|
||||||
|
|
||||||
for benchmark_group in type_grouped_benchmarks:
|
for benchmark_group in type_grouped_benchmarks:
|
||||||
console.print(f"[cyan]Generated for:[/cyan] [bold]{benchmark_group.type_}[/bold]")
|
console.print(f"[cyan]Generated for:[/cyan] [bold]{benchmark_group.type_}[/bold]")
|
||||||
console.print(f" [green]✓[/green] {benchmark_group.type_}_comparison.png")
|
console.print(f" [green]✓[/green] {benchmark_group.type_}_comparison.png")
|
||||||
console.print(f" [green]✓[/green] {benchmark_group.type_}.json\n")
|
console.print(f" [green]✓[/green] {benchmark_group.type_}.json\n")
|
||||||
|
|
||||||
console.print(f"[bold green]✓ Release report generated successfully[/bold green]")
|
console.print("[bold green]✓ Release report generated successfully[/bold green]")
|
||||||
console.print(f"[cyan]Output directory:[/cyan] [bold]{output_dir}[/bold]")
|
console.print(f"[cyan]Output directory:[/cyan] [bold]{output_dir}[/bold]")
|
||||||
|
|
||||||
|
|
||||||
@@ -136,26 +152,33 @@ def release_generate_handler(_: Response) -> None:
|
|||||||
Command(
|
Command(
|
||||||
"diagrams-generate",
|
"diagrams-generate",
|
||||||
description="Generate diagrams for all benchmarks",
|
description="Generate diagrams for all benchmarks",
|
||||||
flags=Flags([
|
flags=Flags(
|
||||||
Flag('without-gc', possible_values=PossibleValues.NEITHER),
|
[
|
||||||
Flag('iterations', possible_values=POSITIVE_INTEGER_PATTERN)
|
Flag("without-gc", possible_values=PossibleValues.NEITHER),
|
||||||
])
|
Flag("iterations", possible_values=POSITIVE_INTEGER_PATTERN),
|
||||||
|
]
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def diagrams_generate_handler(response: Response) -> None:
|
def diagrams_generate_handler(response: Response) -> None:
|
||||||
iterations = 100
|
iterations = 100
|
||||||
iterations_flag = response.input_flags.get_flag_by_name("iterations", with_status=ValidationStatus.VALID)
|
iterations_flag = response.input_flags.get_flag_by_name(
|
||||||
|
"iterations", with_status=ValidationStatus.VALID
|
||||||
|
)
|
||||||
if iterations_flag:
|
if iterations_flag:
|
||||||
iterations = int(iterations_flag.input_value)
|
iterations = int(iterations_flag.input_value)
|
||||||
|
|
||||||
is_gc_disabled = bool(response.input_flags.get_flag_by_name("without-gc", with_status=ValidationStatus.VALID))
|
is_gc_disabled = bool(
|
||||||
|
response.input_flags.get_flag_by_name("without-gc", with_status=ValidationStatus.VALID)
|
||||||
|
)
|
||||||
|
|
||||||
console.print("[cyan]Running all benchmarks...[/cyan]")
|
console.print("[cyan]Running all benchmarks...[/cyan]")
|
||||||
console.print(f"[dim]Iterations: {iterations}, GC Disabled: {is_gc_disabled}[/dim]\n")
|
console.print(f"[dim]Iterations: {iterations}, GC Disabled: {is_gc_disabled}[/dim]\n")
|
||||||
|
|
||||||
type_grouped_benchmarks: list[BenchmarkGroupResult] = registered_benchmarks.run_benchmarks_grouped_by_type(
|
type_grouped_benchmarks: list[BenchmarkGroupResult] = (
|
||||||
iterations=iterations,
|
registered_benchmarks.run_benchmarks_grouped_by_type(
|
||||||
is_gc_disabled=is_gc_disabled
|
iterations=iterations, is_gc_disabled=is_gc_disabled
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
@@ -164,7 +187,7 @@ def diagrams_generate_handler(response: Response) -> None:
|
|||||||
|
|
||||||
diagram_generator = DiagramGenerator(output_dir)
|
diagram_generator = DiagramGenerator(output_dir)
|
||||||
|
|
||||||
console.print(f"[green]✓[/green] Benchmarks completed. Generating diagrams...\n")
|
console.print("[green]✓[/green] Benchmarks completed. Generating diagrams...\n")
|
||||||
|
|
||||||
generated_count = 0
|
generated_count = 0
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from .diagram_generator import DiagramGenerator
|
from .diagram_generator import DiagramGenerator
|
||||||
|
from .release_generator import ReleaseGenerator
|
||||||
from .report_table_generator import ReportTableGenerator
|
from .report_table_generator import ReportTableGenerator
|
||||||
from .system_info_reader import get_system_info
|
from .system_info_reader import get_system_info
|
||||||
from .release_generator import ReleaseGenerator
|
|
||||||
|
|
||||||
__all__ = ["DiagramGenerator", "ReportTableGenerator", "get_system_info", "ReleaseGenerator"]
|
__all__ = ["DiagramGenerator", "ReportTableGenerator", "get_system_info", "ReleaseGenerator"]
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ class DiagramGenerator:
|
|||||||
def __init__(self, output_dir: Path | str) -> None:
|
def __init__(self, output_dir: Path | str) -> None:
|
||||||
self.output_dir: Path = Path(output_dir) if isinstance(output_dir, str) else output_dir
|
self.output_dir: Path = Path(output_dir) if isinstance(output_dir, str) else output_dir
|
||||||
|
|
||||||
matplotlib.use('Agg')
|
matplotlib.use("Agg")
|
||||||
plt.style.use('seaborn-v0_8-whitegrid')
|
plt.style.use("seaborn-v0_8-whitegrid")
|
||||||
|
|
||||||
def generate_comparison_diagram(self, benchmark_group: BenchmarkGroupResult) -> Path:
|
def generate_comparison_diagram(self, benchmark_group: BenchmarkGroupResult) -> Path:
|
||||||
results = benchmark_group.benchmark_results
|
results = benchmark_group.benchmark_results
|
||||||
@@ -27,7 +27,7 @@ class DiagramGenerator:
|
|||||||
max_value = max(
|
max_value = max(
|
||||||
max(avg_times) if avg_times else 0,
|
max(avg_times) if avg_times else 0,
|
||||||
max(median_times) if median_times else 0,
|
max(median_times) if median_times else 0,
|
||||||
max(std_devs) if std_devs else 0
|
max(std_devs) if std_devs else 0,
|
||||||
)
|
)
|
||||||
y_limit = max_value / 0.85 if max_value > 0 else 1.0
|
y_limit = max_value / 0.85 if max_value > 0 else 1.0
|
||||||
|
|
||||||
@@ -41,34 +41,77 @@ class DiagramGenerator:
|
|||||||
x_median = [x + bar_width for x in x_positions]
|
x_median = [x + bar_width for x in x_positions]
|
||||||
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
fig, ax = plt.subplots(figsize=(16, 8))
|
||||||
fig.patch.set_facecolor('white')
|
fig.patch.set_facecolor("white")
|
||||||
|
|
||||||
bars_std = ax.bar(x_std_dev, std_devs, bar_width, label='Std Deviation',
|
bars_std = ax.bar(
|
||||||
color='#2ecc71', alpha=0.9, edgecolor='#27ae60', linewidth=1.5)
|
x_std_dev,
|
||||||
bars_avg = ax.bar(x_avg, avg_times, bar_width, label='Average Time',
|
std_devs,
|
||||||
color='#3498db', alpha=0.9, edgecolor='#2980b9', linewidth=1.5)
|
bar_width,
|
||||||
bars_median = ax.bar(x_median, median_times, bar_width, label='Median Time',
|
label="Std Deviation",
|
||||||
color='#e74c3c', alpha=0.9, edgecolor='#c0392b', linewidth=1.5)
|
color="#2ecc71",
|
||||||
|
alpha=0.9,
|
||||||
|
edgecolor="#27ae60",
|
||||||
|
linewidth=1.5,
|
||||||
|
)
|
||||||
|
bars_avg = ax.bar(
|
||||||
|
x_avg,
|
||||||
|
avg_times,
|
||||||
|
bar_width,
|
||||||
|
label="Average Time",
|
||||||
|
color="#3498db",
|
||||||
|
alpha=0.9,
|
||||||
|
edgecolor="#2980b9",
|
||||||
|
linewidth=1.5,
|
||||||
|
)
|
||||||
|
bars_median = ax.bar(
|
||||||
|
x_median,
|
||||||
|
median_times,
|
||||||
|
bar_width,
|
||||||
|
label="Median Time",
|
||||||
|
color="#e74c3c",
|
||||||
|
alpha=0.9,
|
||||||
|
edgecolor="#c0392b",
|
||||||
|
linewidth=1.5,
|
||||||
|
)
|
||||||
|
|
||||||
for bar_group in [bars_std, bars_avg, bars_median]:
|
for bar_group in [bars_std, bars_avg, bars_median]:
|
||||||
for bar in bar_group:
|
for bar in bar_group:
|
||||||
height = bar.get_height()
|
height = bar.get_height()
|
||||||
ax.text(
|
ax.text(
|
||||||
bar.get_x() + bar.get_width() / 2.,
|
bar.get_x() + bar.get_width() / 2.0,
|
||||||
height,
|
height,
|
||||||
f'{height:.3f}',
|
f"{height:.3f}",
|
||||||
ha='center', va='bottom', fontsize=9, fontweight='bold'
|
ha="center",
|
||||||
|
va="bottom",
|
||||||
|
fontsize=9,
|
||||||
|
fontweight="bold",
|
||||||
)
|
)
|
||||||
|
|
||||||
ax.set_ylabel('Time (ms)', fontsize=14, fontweight='bold', labelpad=10)
|
ax.set_ylabel("Time (ms)", fontsize=14, fontweight="bold", labelpad=10)
|
||||||
|
|
||||||
title_text = f'{benchmark_group.type_.replace("_", " ").title()}'
|
title_text = f"{benchmark_group.type_.replace('_', ' ').title()}"
|
||||||
metadata_text = f'Iterations: {benchmark_group.iterations} | GC: {"Disabled" if benchmark_group.is_gc_disabled else "Enabled"}'
|
metadata_text = f"Iterations: {benchmark_group.iterations} | GC: {'Disabled' if benchmark_group.is_gc_disabled else 'Enabled'}"
|
||||||
|
|
||||||
ax.text(0.5, 1.08, title_text, transform=ax.transAxes,
|
ax.text(
|
||||||
fontsize=18, fontweight='bold', ha='center', color='#2c3e50')
|
0.5,
|
||||||
ax.text(0.5, 1.03, metadata_text, transform=ax.transAxes,
|
1.08,
|
||||||
fontsize=12, ha='center', color='#7f8c8d', style='italic')
|
title_text,
|
||||||
|
transform=ax.transAxes,
|
||||||
|
fontsize=18,
|
||||||
|
fontweight="bold",
|
||||||
|
ha="center",
|
||||||
|
color="#2c3e50",
|
||||||
|
)
|
||||||
|
ax.text(
|
||||||
|
0.5,
|
||||||
|
1.03,
|
||||||
|
metadata_text,
|
||||||
|
transform=ax.transAxes,
|
||||||
|
fontsize=12,
|
||||||
|
ha="center",
|
||||||
|
color="#7f8c8d",
|
||||||
|
style="italic",
|
||||||
|
)
|
||||||
|
|
||||||
ax.set_xticks(x_positions)
|
ax.set_xticks(x_positions)
|
||||||
ax.set_xticklabels([])
|
ax.set_xticklabels([])
|
||||||
@@ -79,23 +122,32 @@ class DiagramGenerator:
|
|||||||
text_x_pos,
|
text_x_pos,
|
||||||
y_limit * 0.02,
|
y_limit * 0.02,
|
||||||
desc,
|
desc,
|
||||||
rotation=90, va='bottom', ha='right', fontsize=10,
|
rotation=90,
|
||||||
color='#2c3e50'
|
va="bottom",
|
||||||
|
ha="right",
|
||||||
|
fontsize=10,
|
||||||
|
color="#2c3e50",
|
||||||
)
|
)
|
||||||
|
|
||||||
ax.set_ylim(0, y_limit)
|
ax.set_ylim(0, y_limit)
|
||||||
|
|
||||||
legend = ax.legend(loc='upper left', fontsize=12, framealpha=0.95,
|
legend = ax.legend(
|
||||||
edgecolor='#34495e', fancybox=True, shadow=True)
|
loc="upper left",
|
||||||
legend.get_frame().set_facecolor('#ecf0f1')
|
fontsize=12,
|
||||||
|
framealpha=0.95,
|
||||||
|
edgecolor="#34495e",
|
||||||
|
fancybox=True,
|
||||||
|
shadow=True,
|
||||||
|
)
|
||||||
|
legend.get_frame().set_facecolor("#ecf0f1")
|
||||||
|
|
||||||
ax.grid(axis='y', alpha=0.4, linestyle='--', linewidth=0.8)
|
ax.grid(axis="y", alpha=0.4, linestyle="--", linewidth=0.8)
|
||||||
ax.set_axisbelow(True)
|
ax.set_axisbelow(True)
|
||||||
|
|
||||||
ax.spines['top'].set_visible(False)
|
ax.spines["top"].set_visible(False)
|
||||||
ax.spines['right'].set_visible(False)
|
ax.spines["right"].set_visible(False)
|
||||||
ax.spines['left'].set_color('#7f8c8d')
|
ax.spines["left"].set_color("#7f8c8d")
|
||||||
ax.spines['bottom'].set_color('#7f8c8d')
|
ax.spines["bottom"].set_color("#7f8c8d")
|
||||||
|
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
|
|
||||||
@@ -104,7 +156,7 @@ class DiagramGenerator:
|
|||||||
|
|
||||||
self.output_dir.mkdir(parents=True, exist_ok=True)
|
self.output_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
plt.savefig(output_path, dpi=200, bbox_inches='tight', facecolor='white')
|
plt.savefig(output_path, dpi=200, bbox_inches="tight", facecolor="white")
|
||||||
plt.close(fig)
|
plt.close(fig)
|
||||||
|
|
||||||
return output_path
|
return output_path
|
||||||
|
|||||||
@@ -36,14 +36,14 @@ class ReleaseGenerator:
|
|||||||
"description": br.description,
|
"description": br.description,
|
||||||
"avg_time": br.avg_time,
|
"avg_time": br.avg_time,
|
||||||
"median_time": br.median_time,
|
"median_time": br.median_time,
|
||||||
"std_dev": br.std_dev
|
"std_dev": br.std_dev,
|
||||||
}
|
}
|
||||||
for br in benchmark_group.benchmark_results
|
for br in benchmark_group.benchmark_results
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
json_path = type_dir / f"{benchmark_group.type_}.json"
|
json_path = type_dir / f"{benchmark_group.type_}.json"
|
||||||
with open(json_path, 'w', encoding='utf-8') as f:
|
with open(json_path, "w", encoding="utf-8") as f:
|
||||||
json.dump(json_data, f, indent=2, ensure_ascii=False)
|
json.dump(json_data, f, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
return self.output_dir
|
return self.output_dir
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from rich.table import Table
|
|||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
|
|
||||||
from ..benchmarks.core.models import BenchmarkGroupResult
|
from ..benchmarks.core.models import BenchmarkGroupResult
|
||||||
from metrics.services.system_info_reader import SystemInfo
|
from .system_info_reader import SystemInfo
|
||||||
|
|
||||||
|
|
||||||
class ReportTableGenerator:
|
class ReportTableGenerator:
|
||||||
@@ -12,11 +12,15 @@ class ReportTableGenerator:
|
|||||||
self._cached_benchmark_tables: dict[int, Table] = {}
|
self._cached_benchmark_tables: dict[int, Table] = {}
|
||||||
self._cached_system_info_table: Table | None = None
|
self._cached_system_info_table: Table | None = None
|
||||||
|
|
||||||
def generate_benchmark_report_table(self, benchmark_group_result: BenchmarkGroupResult) -> Table:
|
def generate_benchmark_report_table(
|
||||||
|
self, benchmark_group_result: BenchmarkGroupResult
|
||||||
|
) -> Table:
|
||||||
if cached_result := self._cached_benchmark_tables.get(id(benchmark_group_result)):
|
if cached_result := self._cached_benchmark_tables.get(id(benchmark_group_result)):
|
||||||
return cached_result
|
return cached_result
|
||||||
|
|
||||||
table = Table(show_header=True, header_style="bold cyan", border_style="blue", show_lines=True)
|
table = Table(
|
||||||
|
show_header=True, header_style="bold cyan", border_style="blue", show_lines=True
|
||||||
|
)
|
||||||
table.add_column("Description", style="dim")
|
table.add_column("Description", style="dim")
|
||||||
table.add_column("Avg Time", justify="right", style="bold yellow")
|
table.add_column("Avg Time", justify="right", style="bold yellow")
|
||||||
table.add_column("Median Time", justify="right", style="bold yellow")
|
table.add_column("Median Time", justify="right", style="bold yellow")
|
||||||
@@ -34,18 +38,22 @@ class ReportTableGenerator:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generate_benchmark_table_header(benchmark_group_result: BenchmarkGroupResult) -> Panel:
|
def generate_benchmark_table_header(benchmark_group_result: BenchmarkGroupResult) -> Panel:
|
||||||
header_text = Text(f"TYPE: {benchmark_group_result.type_.upper()} ; "
|
header_text = Text(
|
||||||
|
f"TYPE: {benchmark_group_result.type_.upper()} ; "
|
||||||
f"ITERATIONS: {benchmark_group_result.iterations} ; "
|
f"ITERATIONS: {benchmark_group_result.iterations} ; "
|
||||||
f"GC {"DISABLED" if benchmark_group_result.is_gc_disabled else "ENABLED"} ; "
|
f"GC {'DISABLED' if benchmark_group_result.is_gc_disabled else 'ENABLED'} ; "
|
||||||
f"ALL TIME IN MS",
|
f"ALL TIME IN MS",
|
||||||
style="bold magenta")
|
style="bold magenta",
|
||||||
|
)
|
||||||
return Panel(header_text, expand=False, border_style="magenta")
|
return Panel(header_text, expand=False, border_style="magenta")
|
||||||
|
|
||||||
def generate_system_info_table(self) -> Table:
|
def generate_system_info_table(self) -> Table:
|
||||||
if self._cached_system_info_table is not None:
|
if self._cached_system_info_table is not None:
|
||||||
return self._cached_system_info_table
|
return self._cached_system_info_table
|
||||||
|
|
||||||
table = Table(show_header=True, header_style="bold cyan", border_style="blue", show_lines=True)
|
table = Table(
|
||||||
|
show_header=True, header_style="bold cyan", border_style="blue", show_lines=True
|
||||||
|
)
|
||||||
table.add_column("Parameter", style="green")
|
table.add_column("Parameter", style="green")
|
||||||
table.add_column("Value", style="yellow")
|
table.add_column("Value", style="yellow")
|
||||||
|
|
||||||
@@ -55,10 +63,10 @@ class ReportTableGenerator:
|
|||||||
table.add_row("CPU", self.system_info.cpu_info.name)
|
table.add_row("CPU", self.system_info.cpu_info.name)
|
||||||
table.add_row("CPU Physical Cores", str(self.system_info.cpu_info.physical_cores))
|
table.add_row("CPU Physical Cores", str(self.system_info.cpu_info.physical_cores))
|
||||||
table.add_row("CPU Logical Cores", str(self.system_info.cpu_info.logical_cores))
|
table.add_row("CPU Logical Cores", str(self.system_info.cpu_info.logical_cores))
|
||||||
table.add_row("CPU Max Frequency", str(self.system_info.cpu_info.max_frequency) + ' GHz')
|
table.add_row("CPU Max Frequency", str(self.system_info.cpu_info.max_frequency) + " GHz")
|
||||||
table.add_row("Total RAM", str(self.system_info.memory_info.total_ram) + ' GB')
|
table.add_row("Total RAM", str(self.system_info.memory_info.total_ram) + " GB")
|
||||||
table.add_row("Used RAM", str(self.system_info.memory_info.used_ram) + ' GB')
|
table.add_row("Used RAM", str(self.system_info.memory_info.used_ram) + " GB")
|
||||||
table.add_row("Available RAM", str(self.system_info.memory_info.available_ram) + ' GB')
|
table.add_row("Available RAM", str(self.system_info.memory_info.available_ram) + " GB")
|
||||||
table.add_row("Python Version", self.system_info.python_info.version)
|
table.add_row("Python Version", self.system_info.python_info.version)
|
||||||
table.add_row("Python Implementation", self.system_info.python_info.implementation)
|
table.add_row("Python Implementation", self.system_info.python_info.implementation)
|
||||||
table.add_row("Python Compiler", self.system_info.python_info.compiler)
|
table.add_row("Python Compiler", self.system_info.python_info.compiler)
|
||||||
|
|||||||
@@ -1,28 +1,19 @@
|
|||||||
__all__ = [
|
__all__ = ["SystemInfo", "get_system_info"]
|
||||||
"SystemInfo",
|
|
||||||
"get_system_info"
|
|
||||||
]
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import cpuinfo
|
import cpuinfo
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, slots=True)
|
|
||||||
class SystemInfo:
|
|
||||||
os_info: OSInfo
|
|
||||||
cpu_info: CPUInfo
|
|
||||||
memory_info: MemoryInfo
|
|
||||||
python_info: PythonInfo
|
|
||||||
|
|
||||||
@dataclass(frozen=True, slots=True)
|
@dataclass(frozen=True, slots=True)
|
||||||
class OSInfo:
|
class OSInfo:
|
||||||
name: str
|
name: str
|
||||||
kernel_version: str
|
kernel_version: str
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, slots=True)
|
@dataclass(frozen=True, slots=True)
|
||||||
class CPUInfo:
|
class CPUInfo:
|
||||||
name: str
|
name: str
|
||||||
@@ -31,12 +22,14 @@ class CPUInfo:
|
|||||||
logical_cores: int
|
logical_cores: int
|
||||||
max_frequency: float
|
max_frequency: float
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, slots=True)
|
@dataclass(frozen=True, slots=True)
|
||||||
class MemoryInfo:
|
class MemoryInfo:
|
||||||
total_ram: float # in GB
|
total_ram: float # in GB
|
||||||
used_ram: float # in GB
|
used_ram: float # in GB
|
||||||
available_ram: float # in GB
|
available_ram: float # in GB
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, slots=True)
|
@dataclass(frozen=True, slots=True)
|
||||||
class PythonInfo:
|
class PythonInfo:
|
||||||
version: str
|
version: str
|
||||||
@@ -44,18 +37,6 @@ class PythonInfo:
|
|||||||
compiler: str
|
compiler: str
|
||||||
|
|
||||||
|
|
||||||
def get_system_info() -> SystemInfo:
|
|
||||||
os_info = get_os_info()
|
|
||||||
cpu_info = get_cpu_info()
|
|
||||||
memory_info = get_memory_info()
|
|
||||||
python_info = get_python_info()
|
|
||||||
return SystemInfo(
|
|
||||||
os_info=os_info,
|
|
||||||
cpu_info=cpu_info,
|
|
||||||
memory_info=memory_info,
|
|
||||||
python_info=python_info,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_os_info() -> OSInfo:
|
def get_os_info() -> OSInfo:
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
|
|
||||||
@@ -73,22 +54,17 @@ def get_os_info() -> OSInfo:
|
|||||||
kernel_version=kernel_version,
|
kernel_version=kernel_version,
|
||||||
)
|
)
|
||||||
elif system == "Darwin":
|
elif system == "Darwin":
|
||||||
return OSInfo(
|
return OSInfo(kernel_version=platform.release(), name=f"macOS {platform.mac_ver()[0]}")
|
||||||
kernel_version=platform.release(),
|
|
||||||
name=f"macOS {platform.mac_ver()[0]}"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
return OSInfo(
|
return OSInfo(kernel_version=platform.release(), name=platform.system())
|
||||||
kernel_version=platform.release(),
|
|
||||||
name=platform.system()
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_cpu_info() -> CPUInfo:
|
def get_cpu_info() -> CPUInfo:
|
||||||
cpu_info = cpuinfo.get_cpu_info()
|
cpu_info = cpuinfo.get_cpu_info()
|
||||||
cpu_name = cpu_info["brand_raw"]
|
cpu_name = cpu_info["brand_raw"]
|
||||||
cpu_architecture = cpu_info["arch"]
|
cpu_architecture = cpu_info["arch"]
|
||||||
cpu_physical_cores = psutil.cpu_count(logical=False)
|
cpu_physical_cores = psutil.cpu_count(logical=False) or 0
|
||||||
cpu_logical_cores = psutil.cpu_count(logical=True)
|
cpu_logical_cores = psutil.cpu_count(logical=True) or 0
|
||||||
|
|
||||||
cpu_freq = psutil.cpu_freq()
|
cpu_freq = psutil.cpu_freq()
|
||||||
cpu_max_frequency = cpu_freq.max
|
cpu_max_frequency = cpu_freq.max
|
||||||
@@ -98,9 +74,10 @@ def get_cpu_info() -> CPUInfo:
|
|||||||
architecture=cpu_architecture,
|
architecture=cpu_architecture,
|
||||||
physical_cores=cpu_physical_cores,
|
physical_cores=cpu_physical_cores,
|
||||||
logical_cores=cpu_logical_cores,
|
logical_cores=cpu_logical_cores,
|
||||||
max_frequency=cpu_max_frequency
|
max_frequency=cpu_max_frequency,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_memory_info() -> MemoryInfo:
|
def get_memory_info() -> MemoryInfo:
|
||||||
mem = psutil.virtual_memory()
|
mem = psutil.virtual_memory()
|
||||||
total_ram = round(mem.total / (1024**3), 2)
|
total_ram = round(mem.total / (1024**3), 2)
|
||||||
@@ -113,14 +90,32 @@ def get_memory_info() -> MemoryInfo:
|
|||||||
available_ram=available_ram,
|
available_ram=available_ram,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_python_info() -> PythonInfo:
|
def get_python_info() -> PythonInfo:
|
||||||
python_version = platform.python_version()
|
python_version = platform.python_version()
|
||||||
python_implementation = platform.python_implementation()
|
python_implementation = platform.python_implementation()
|
||||||
python_compiler = platform.python_compiler()
|
python_compiler = platform.python_compiler()
|
||||||
return PythonInfo(
|
return PythonInfo(
|
||||||
version=python_version,
|
version=python_version, implementation=python_implementation, compiler=python_compiler
|
||||||
implementation=python_implementation,
|
|
||||||
compiler=python_compiler
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, slots=True)
|
||||||
|
class SystemInfo:
|
||||||
|
os_info: OSInfo
|
||||||
|
cpu_info: CPUInfo
|
||||||
|
memory_info: MemoryInfo
|
||||||
|
python_info: PythonInfo
|
||||||
|
|
||||||
|
|
||||||
|
def get_system_info() -> SystemInfo:
|
||||||
|
os_info = get_os_info()
|
||||||
|
cpu_info = get_cpu_info()
|
||||||
|
memory_info = get_memory_info()
|
||||||
|
python_info = get_python_info()
|
||||||
|
return SystemInfo(
|
||||||
|
os_info=os_info,
|
||||||
|
cpu_info=cpu_info,
|
||||||
|
memory_info=memory_info,
|
||||||
|
python_info=python_info,
|
||||||
|
)
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ line-length=100
|
|||||||
|
|
||||||
[tool.pyright]
|
[tool.pyright]
|
||||||
typeCheckingMode = "strict"
|
typeCheckingMode = "strict"
|
||||||
|
reportMissingTypeStubs = false
|
||||||
|
|
||||||
[[tool.pyright.executionEnvironments]]
|
[[tool.pyright.executionEnvironments]]
|
||||||
root = "tests/"
|
root = "tests/"
|
||||||
|
|||||||
Reference in New Issue
Block a user