This commit is contained in:
2026-02-06 23:41:55 +03:00
parent fcff6f4263
commit f1034ff447
15 changed files with 280 additions and 99 deletions
+1
View File
@@ -64,6 +64,7 @@ Argenta предназначена для создания приложений,
root/contributing root/contributing
root/code_of_conduct root/code_of_conduct
root/metrics
.. toctree:: .. toctree::
:hidden: :hidden:
+181
View File
@@ -0,0 +1,181 @@
Метрики
=======
Система метрик ``Argenta`` предоставляет инструменты для измерения производительности ключевых компонентов библиотеки. Это позволяет отслеживать регрессию/прогрессию производительности между релизами и оптимизировать критические участки кода.
-----
Запуск метрик
-------------
Для работы с метриками необходимо склонировать репозиторий и установить зависимости:
.. code-block:: bash
git clone https://github.com/koloideal/Argenta.git
cd Argenta
uv sync --group metrics
Запуск системы метрик:
.. code-block:: bash
python -m metrics
После запуска откроется интерактивная сессия с доступными командами для работы с бенчмарками.
-----
Доступные команды
-----------------
run-all
~~~~~~~
Запускает все зарегистрированные бенчмарки и выводит результаты в виде таблиц.
**Синтаксис:**
.. code-block:: shell
run-all [--without-gc] [--without-system-info]
**Флаги:**
- ``--without-gc`` — отключает сборщик мусора во время выполнения бенчмарков для более стабильных результатов
- ``--without-system-info`` — скрывает информацию о системе в выводе
-----
list-types
~~~~~~~~~~
Выводит список всех доступных типов бенчмарков с количеством тестов в каждой категории.
**Синтаксис:**
.. code-block:: shell
list-types
**Пример вывода:**
.. code-block:: text
Available benchmark types:
• flag_validation (9 benchmarks)
• input_command_parse (7 benchmarks)
• finds_appropriate_handler (5 benchmarks)
-----
run-type
~~~~~~~~
Запускает бенчмарки определённого типа.
**Синтаксис:**
.. code-block:: shell
run-type --type <type_name> [--without-gc] [--without-system-info]
**Флаги:**
- ``--type`` — тип бенчмарков для запуска (обязательный)
- ``--without-gc`` — отключает сборщик мусора
- ``--without-system-info`` — скрывает информацию о системе
-----
diagrams-generate
~~~~~~~~~~~~~~~~~
Генерирует визуальные диаграммы сравнения производительности для всех бенчмарков.
**Синтаксис:**
.. code-block:: shell
diagrams-generate [--iterations <number>] [--without-gc]
**Флаги:**
- ``--iterations`` — количество итераций для каждого бенчмарка (по умолчанию 100)
- ``--without-gc`` — отключает сборщик мусора
Диаграммы сохраняются в директорию ``metrics/reports/diagrams/<timestamp>/``.
-----
release-generate
~~~~~~~~~~~~~~~~
Генерирует полный отчёт о производительности для текущей версии библиотеки. Используется при подготовке релизов.
**Синтаксис:**
.. code-block:: shell
release-generate
Команда автоматически:
1. Определяет текущую версию библиотеки
2. Запускает все бенчмарки с 1000 итераций и отключённым GC
3. Генерирует JSON-отчёты и диаграммы сравнения
4. Сохраняет результаты в ``metrics/reports/releases/<version>/``
-----
Интерпретация результатов
-------------------------
Результаты бенчмарков включают следующие метрики:
**Среднее время (mean)**
Среднее время выполнения операции. Основная метрика для сравнения производительности.
**Медиана (median)**
Медианное значение времени выполнения. Менее чувствительна к выбросам, чем среднее.
**Стандартное отклонение (std)**
Показывает стабильность измерений. Меньшее значение означает более предсказуемую производительность.
-----
Рекомендации по использованию
------------------------------
**Для оптимизации**
Используйте ``run-type`` для фокусировки на конкретной области и ``--without-gc`` для более точных измерений.
**Для визуализации**
Команда ``diagrams-generate`` создаёт наглядные графики, удобные для презентаций и документации.
**Для стабильных результатов**
Закройте ресурсоёмкие приложения, используйте флаг ``--without-gc`` и увеличивайте количество итераций через ``--iterations``.
-----
Добавление новых бенчмарков
----------------------------
Вы можете реализовать свои бенчмарки для тестирования специфичных юнитов библиотеки. Новые бенчмарки добавляются через декоратор ``@benchmarks.register``:
.. code-block:: python
from metrics.benchmarks.entity import benchmarks
@benchmarks.register(
type_="my_category",
description="Description of what is being measured"
)
def benchmark_my_operation() -> None:
# Код, производительность которого измеряется
pass
.. important::
Бенчмарк должен быть импортирован в ``metrics/benchmarks/__init__.py`` для автоматической регистрации.
@@ -6,37 +6,37 @@
{ {
"name": "benchmark_simple_command", "name": "benchmark_simple_command",
"description": "Simple command (no flags)", "description": "Simple command (no flags)",
"avg_time": 0.0354, "avg_time": 0.036,
"median_time": 0.0345, "median_time": 0.0354,
"std_dev": 0.0056 "std_dev": 0.0087
}, },
{ {
"name": "benchmark_command_with_flags", "name": "benchmark_command_with_flags",
"description": "Command with flags (3 flags)", "description": "Command with flags (3 flags)",
"avg_time": 0.0544, "avg_time": 0.0557,
"median_time": 0.0536, "median_time": 0.0545,
"std_dev": 0.009 "std_dev": 0.0171
}, },
{ {
"name": "benchmark_many_commands", "name": "benchmark_many_commands",
"description": "Many commands (50 commands)", "description": "Many commands (50 commands)",
"avg_time": 1.009, "avg_time": 1.0453,
"median_time": 1.0022, "median_time": 1.0388,
"std_dev": 0.039 "std_dev": 0.0322
}, },
{ {
"name": "benchmark_command_with_many_flags", "name": "benchmark_command_with_many_flags",
"description": "Command with many flags (20 flags)", "description": "Command with many flags (20 flags)",
"avg_time": 0.131, "avg_time": 0.1322,
"median_time": 0.1298, "median_time": 0.131,
"std_dev": 0.0054 "std_dev": 0.0045
}, },
{ {
"name": "benchmark_extreme_router", "name": "benchmark_extreme_router",
"description": "Extreme (100 commands, 10 flags each)", "description": "Extreme (100 commands, 10 flags each)",
"avg_time": 3.1818, "avg_time": 3.2471,
"median_time": 3.1619, "median_time": 3.235,
"std_dev": 0.1673 "std_dev": 0.0814
} }
] ]
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 156 KiB

@@ -6,9 +6,9 @@
{ {
"name": "benchmark_validate_all_single_flag", "name": "benchmark_validate_all_single_flag",
"description": "Single flag with PossibleValues.ALL", "description": "Single flag with PossibleValues.ALL",
"avg_time": 0.0009, "avg_time": 0.0008,
"median_time": 0.0009, "median_time": 0.0008,
"std_dev": 0.0003 "std_dev": 0.0002
}, },
{ {
"name": "benchmark_validate_neither_single_flag", "name": "benchmark_validate_neither_single_flag",
@@ -21,50 +21,50 @@
"name": "benchmark_validate_list_small", "name": "benchmark_validate_list_small",
"description": "List validation (5 possible values)", "description": "List validation (5 possible values)",
"avg_time": 0.001, "avg_time": 0.001,
"median_time": 0.001, "median_time": 0.0009,
"std_dev": 0.0003 "std_dev": 0.0007
}, },
{ {
"name": "benchmark_validate_list_large", "name": "benchmark_validate_list_large",
"description": "List validation (50 possible values)", "description": "List validation (50 possible values)",
"avg_time": 0.0079, "avg_time": 0.0079,
"median_time": 0.0078, "median_time": 0.0078,
"std_dev": 0.0007 "std_dev": 0.0021
}, },
{ {
"name": "benchmark_validate_regex_simple", "name": "benchmark_validate_regex_simple",
"description": "Regex validation (simple pattern)", "description": "Regex validation (simple pattern)",
"avg_time": 0.0019, "avg_time": 0.0017,
"median_time": 0.0016, "median_time": 0.0016,
"std_dev": 0.0073 "std_dev": 0.0028
}, },
{ {
"name": "benchmark_validate_regex_complex", "name": "benchmark_validate_regex_complex",
"description": "Regex validation (complex pattern)", "description": "Regex validation (complex pattern)",
"avg_time": 0.0018, "avg_time": 0.0018,
"median_time": 0.0017, "median_time": 0.0016,
"std_dev": 0.0051 "std_dev": 0.0051
}, },
{ {
"name": "benchmark_validate_multiple_flags_10", "name": "benchmark_validate_multiple_flags_10",
"description": "Multiple flags validation (10 flags)", "description": "Multiple flags validation (10 flags)",
"avg_time": 0.0147, "avg_time": 0.0145,
"median_time": 0.0146, "median_time": 0.0144,
"std_dev": 0.0013 "std_dev": 0.0013
}, },
{ {
"name": "benchmark_validate_multiple_flags_50", "name": "benchmark_validate_multiple_flags_50",
"description": "Multiple flags validation (50 flags)", "description": "Multiple flags validation (50 flags)",
"avg_time": 0.0669, "avg_time": 0.0661,
"median_time": 0.0661, "median_time": 0.0658,
"std_dev": 0.0025 "std_dev": 0.0024
}, },
{ {
"name": "benchmark_validate_extreme_100_flags", "name": "benchmark_validate_extreme_100_flags",
"description": "Extreme (100 flags with regex validation)", "description": "Extreme (100 flags with regex validation)",
"avg_time": 0.1626, "avg_time": 0.1599,
"median_time": 0.1609, "median_time": 0.1589,
"std_dev": 0.007 "std_dev": 0.0065
} }
] ]
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 186 KiB

@@ -6,51 +6,51 @@
{ {
"name": "benchmark_parse_simple_command", "name": "benchmark_parse_simple_command",
"description": "Simple command (no flags)", "description": "Simple command (no flags)",
"avg_time": 0.0099, "avg_time": 0.0096,
"median_time": 0.0098, "median_time": 0.0095,
"std_dev": 0.0014 "std_dev": 0.0012
}, },
{ {
"name": "benchmark_command_with_few_flags", "name": "benchmark_command_with_few_flags",
"description": "Command with few flags (3 flags)", "description": "Command with few flags (3 flags)",
"avg_time": 0.0214, "avg_time": 0.0216,
"median_time": 0.0211, "median_time": 0.0213,
"std_dev": 0.003 "std_dev": 0.0021
}, },
{ {
"name": "benchmark_command_with_flags_and_values", "name": "benchmark_command_with_flags_and_values",
"description": "Command with flags and values (5 flags)", "description": "Command with flags and values (5 flags)",
"avg_time": 0.0598, "avg_time": 0.06,
"median_time": 0.0591, "median_time": 0.0595,
"std_dev": 0.0041 "std_dev": 0.0025
}, },
{ {
"name": "benchmark_command_with_mixed_prefixes", "name": "benchmark_command_with_mixed_prefixes",
"description": "Command with mixed prefixes (-, --, ---)", "description": "Command with mixed prefixes (-, --, ---)",
"avg_time": 0.0545, "avg_time": 0.0542,
"median_time": 0.0541, "median_time": 0.0538,
"std_dev": 0.0024 "std_dev": 0.0028
}, },
{ {
"name": "benchmark_command_with_long_values", "name": "benchmark_command_with_long_values",
"description": "Command with long values (10 flags)", "description": "Command with long values (10 flags)",
"avg_time": 0.2114, "avg_time": 0.2092,
"median_time": 0.2103, "median_time": 0.2082,
"std_dev": 0.0068 "std_dev": 0.0067
}, },
{ {
"name": "benchmark_command_with_quoted_values", "name": "benchmark_command_with_quoted_values",
"description": "Command with quoted values (5 flags)", "description": "Command with quoted values (5 flags)",
"avg_time": 0.0489, "avg_time": 0.0481,
"median_time": 0.0488, "median_time": 0.0477,
"std_dev": 0.0019 "std_dev": 0.0023
}, },
{ {
"name": "benchmark_extreme_many_flags", "name": "benchmark_extreme_many_flags",
"description": "Extreme (50 flags with values)", "description": "Extreme (50 flags with values)",
"avg_time": 0.8057, "avg_time": 0.7907,
"median_time": 0.7997, "median_time": 0.7884,
"std_dev": 0.024 "std_dev": 0.0417
} }
] ]
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 164 KiB

@@ -6,37 +6,37 @@
{ {
"name": "benchmark_few_commands", "name": "benchmark_few_commands",
"description": "Few commands (10 commands, no match)", "description": "Few commands (10 commands, no match)",
"avg_time": 0.207, "avg_time": 0.251,
"median_time": 0.2051, "median_time": 0.2488,
"std_dev": 0.01 "std_dev": 0.012
}, },
{ {
"name": "benchmark_many_commands_most_similar", "name": "benchmark_many_commands_most_similar",
"description": "Many commands (50 commands, no match)", "description": "Many commands (50 commands, no match)",
"avg_time": 1.0116, "avg_time": 1.1933,
"median_time": 1.0074, "median_time": 1.1878,
"std_dev": 0.0306 "std_dev": 0.0305
}, },
{ {
"name": "benchmark_many_aliases", "name": "benchmark_many_aliases",
"description": "Many aliases (20 commands, 10 aliases each)", "description": "Many aliases (20 commands, 10 aliases each)",
"avg_time": 0.6857, "avg_time": 1.2151,
"median_time": 0.6672, "median_time": 1.2124,
"std_dev": 0.0811 "std_dev": 0.0282
}, },
{ {
"name": "benchmark_partial_match", "name": "benchmark_partial_match",
"description": "Partial match (50 commands, prefix match)", "description": "Partial match (50 commands, prefix match)",
"avg_time": 1.0218, "avg_time": 1.6781,
"median_time": 1.0192, "median_time": 1.6689,
"std_dev": 0.0232 "std_dev": 0.0573
}, },
{ {
"name": "benchmark_extreme_commands", "name": "benchmark_extreme_commands",
"description": "Extreme (100 commands, 20 aliases each)", "description": "Extreme (100 commands, 20 aliases each)",
"avg_time": 6.4118, "avg_time": 10.5539,
"median_time": 6.4225, "median_time": 10.5288,
"std_dev": 0.2008 "std_dev": 0.1603
} }
] ]
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 168 KiB

@@ -6,37 +6,37 @@
{ {
"name": "benchmark_no_aliases", "name": "benchmark_no_aliases",
"description": "With no aliases", "description": "With no aliases",
"avg_time": 8.9994, "avg_time": 7.4799,
"median_time": 8.9559, "median_time": 7.4576,
"std_dev": 0.242 "std_dev": 0.1645
}, },
{ {
"name": "benchmark_few_aliases", "name": "benchmark_few_aliases",
"description": "With few aliases (6 total)", "description": "With few aliases (6 total)",
"avg_time": 8.957, "avg_time": 7.4135,
"median_time": 8.936, "median_time": 7.4061,
"std_dev": 0.2296 "std_dev": 0.1709
}, },
{ {
"name": "benchmark_with_many_aliases", "name": "benchmark_with_many_aliases",
"description": "With many aliases (15 total)", "description": "With many aliases (15 total)",
"avg_time": 8.9953, "avg_time": 7.4018,
"median_time": 8.9721, "median_time": 7.3943,
"std_dev": 0.2243 "std_dev": 0.1589
}, },
{ {
"name": "benchmark_very_many_aliases", "name": "benchmark_very_many_aliases",
"description": "With very many aliases (60 total)", "description": "With very many aliases (60 total)",
"avg_time": 9.0155, "avg_time": 7.476,
"median_time": 8.9992, "median_time": 7.4575,
"std_dev": 0.2433 "std_dev": 0.2156
}, },
{ {
"name": "benchmark_extreme_aliases", "name": "benchmark_extreme_aliases",
"description": "With extreme aliases (300 total)", "description": "With extreme aliases (300 total)",
"avg_time": 9.2977, "avg_time": 7.7167,
"median_time": 9.255, "median_time": 7.706,
"std_dev": 0.3884 "std_dev": 0.2052
} }
] ]
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 130 KiB

@@ -6,37 +6,37 @@
{ {
"name": "benchmark_few_routers", "name": "benchmark_few_routers",
"description": "With few routers (3 routers, 1 command each)", "description": "With few routers (3 routers, 1 command each)",
"avg_time": 0.0912, "avg_time": 0.0959,
"median_time": 0.0901, "median_time": 0.0944,
"std_dev": 0.0051 "std_dev": 0.0097
}, },
{ {
"name": "benchmark_many_routers", "name": "benchmark_many_routers",
"description": "With many routers (10 routers, 1 command each)", "description": "With many routers (10 routers, 1 command each)",
"avg_time": 0.2433, "avg_time": 0.2488,
"median_time": 0.2382, "median_time": 0.2467,
"std_dev": 0.0292 "std_dev": 0.0081
}, },
{ {
"name": "benchmark_many_commands_per_router", "name": "benchmark_many_commands_per_router",
"description": "With many commands per router (3 routers, 10 commands each)", "description": "With many commands per router (3 routers, 10 commands each)",
"avg_time": 0.6157, "avg_time": 0.6474,
"median_time": 0.6132, "median_time": 0.6401,
"std_dev": 0.0199 "std_dev": 0.0304
}, },
{ {
"name": "benchmark_many_aliases_per_command", "name": "benchmark_many_aliases_per_command",
"description": "With many aliases (3 routers, 5 commands, 10 aliases each)", "description": "With many aliases (3 routers, 5 commands, 10 aliases each)",
"avg_time": 0.516, "avg_time": 0.5261,
"median_time": 0.5082, "median_time": 0.5156,
"std_dev": 0.0403 "std_dev": 0.0475
}, },
{ {
"name": "benchmark_extreme_routers", "name": "benchmark_extreme_routers",
"description": "Extreme (20 routers, 10 commands, 20 aliases each)", "description": "Extreme (20 routers, 10 commands, 20 aliases each)",
"avg_time": 10.8103, "avg_time": 9.9128,
"median_time": 10.7871, "median_time": 9.9518,
"std_dev": 0.2788 "std_dev": 0.2373
} }
] ]
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 179 KiB

-1
View File
@@ -119,7 +119,6 @@ class BaseApp(BehaviorHandlersSettersMixin):
def _most_similar_command(self, unknown_command: str) -> str | None: def _most_similar_command(self, unknown_command: str) -> str | None:
all_commands = self.registered_routers.get_triggers() all_commands = self.registered_routers.get_triggers()
print(all_commands)
matches = difflib.get_close_matches(unknown_command, all_commands, n=1) matches = difflib.get_close_matches(unknown_command, all_commands, n=1)
return matches[0] if matches else None return matches[0] if matches else None