From 7f488f873ee17a2ed5c789dd8503d0d8811b33ff Mon Sep 17 00:00:00 2001 From: Sergey Penkovsky Date: Wed, 6 Aug 2025 13:35:39 +0300 Subject: [PATCH] docs(benchmarks): update README files with new CLI, matrix run, output formats, and usage instructions (EN+RU) --- benchmark_cherrypick/README.md | 97 +++++++++++++++++++++++------- benchmark_cherrypick/README.ru.md | 99 ++++++++++++++++++++++++------- 2 files changed, 155 insertions(+), 41 deletions(-) diff --git a/benchmark_cherrypick/README.md b/benchmark_cherrypick/README.md index 81fe8a2..74ace69 100644 --- a/benchmark_cherrypick/README.md +++ b/benchmark_cherrypick/README.md @@ -1,28 +1,29 @@ # benchmark_cherrypick -Benchmarks for performance and features of the cherrypick (core) DI container. +Benchmarks for the performance and features of the cherrypick (core) DI container. -All scenarios use the public API capabilities of cherrypick (scope, module, binding, scoping, and async support). +All scenarios use only the public API (scope, module, binding, scoping, and async). ## Scenarios -- **RegisterAndResolve**: basic registration and resolution of a dependency. -- **ChainSingleton (A->B->C, singleton)**: dependency chain, all as singletons. -- **ChainFactory (A->B->C, factory)**: dependency chain with factory bindings (new instance on each request). -- **NamedResolve (by name)**: resolving a named dependency among multiple implementations. -- **AsyncChain (A->B->C, async)**: asynchronous dependency chain. -- **ScopeOverride (child overrides parent)**: overriding a dependency in a child scope over a parent. +- **RegisterAndResolve**: Basic registration and resolution of a dependency. +- **ChainSingleton (A->B->C, singleton)**: Deep dependency chain, all as singletons. +- **ChainFactory (A->B->C, factory)**: Dependency chain with factory bindings (new instance per request). +- **NamedResolve (by name)**: Resolving a named dependency among several implementations. +- **AsyncChain (A->B->C, async)**: Asynchronous dependency chain. +- **ScopeOverride (child overrides parent)**: Overriding a dependency in a child scope over a parent. -## Benchmark results +## Features -| Scenario | RunTime (μs) | -|----------------------------------------------------|---------------| -| RegisterAndResolve | 0.4574 | -| ChainSingleton (A->B->C, singleton) | 0.3759 | -| ChainFactory (A->B->C, factory) | 1.3783 | -| NamedResolve (by name) | 0.5193 | -| AsyncChain (A->B->C, async) | 0.5985 | -| ScopeOverride (child overrides parent) | 0.3611 | +- **Unified benchmark structure**: All test scenarios use a unified base mixin for setup/teardown. +- **Flexible CLI parameterization**: + Run benchmarks with custom parameters for chain length, depth, scenarios and formats. +- **Matrix/mass run support**: + Easily run benchmarks for all combinations of chainLength and depth in one run. +- **Machine and human readable output**: + Supports pretty-table, CSV, and JSON for downstream analytics or data storage. +- **Scenario selection**: + Run all or only specific benchmarks via CLI. ## How to run @@ -30,13 +31,69 @@ All scenarios use the public API capabilities of cherrypick (scope, module, bind ```shell dart pub get ``` -2. Run the benchmarks: +2. Run all benchmarks (with default parameters): ```shell dart run bin/main.dart ``` -A text report with all metrics will be displayed in the console. +### Run with custom parameters + +- Mass run in matrix mode (CSV output): + ```shell + dart run bin/main.dart --benchmark=chain_singleton --chainCount=10,100 --nestingDepth=5,10 --format=csv + ``` + +- Run only the named resolve scenario: + ```shell + dart run bin/main.dart --benchmark=named + ``` + +- See available CLI flags: + ```shell + dart run bin/main.dart --help + ``` + +#### Available CLI options + +- `--benchmark` (or `-b`) — Scenario to run: + `register`, `chain_singleton`, `chain_factory`, `named`, `override`, `async_chain`, `all` (default) +- `--chainCount` (or `-c`) — Comma-separated chain lengths. E.g. `10,100` +- `--nestingDepth` (or `-d`) — Comma-separated chain depths. E.g. `5,10` +- `--format` (or `-f`) — Result output format: `pretty` (table), `csv`, `json` +- `--help` (or `-h`) — Print help + +#### Example output (`--format=csv`) +``` +benchmark,chainCount,nestingDepth,elapsed_us +ChainSingleton,10,5,2450000 +ChainSingleton,10,10,2624000 +ChainSingleton,100,5,2506300 +ChainSingleton,100,10,2856900 +``` --- -To add your custom scenario — just create a new Dart file and declare a class extending BenchmarkBase or AsyncBenchmarkBase, then add its invocation to main.dart. +## Add your own benchmark + +1. Create a Dart file with a class inheriting from `BenchmarkBase` or `AsyncBenchmarkBase`. +2. Use the `BenchmarkWithScope` mixin for automatic Scope management if needed. +3. Add your benchmark to bin/main.dart for selection via CLI. + +--- + +## Example for contributors + +```dart +class MyBenchmark extends BenchmarkBase with BenchmarkWithScope { + MyBenchmark() : super('My custom'); + @override void setup() => setupScope([MyModule()]); + @override void run() { scope.resolve(); } + @override void teardown() => teardownScope(); +} +``` + +--- + +## License + +MIT diff --git a/benchmark_cherrypick/README.ru.md b/benchmark_cherrypick/README.ru.md index 86a9539..37a5690 100644 --- a/benchmark_cherrypick/README.ru.md +++ b/benchmark_cherrypick/README.ru.md @@ -1,42 +1,99 @@ # benchmark_cherrypick -Бенчмарки производительности и функциональности DI-контейнера cherrypick (core). +Бенчмарки производительности и возможностей DI-контейнера cherrypick (core). -Все сценарии используют реальные возможности public API cherrypick (scope, module, binding, scoping и асинхронность). +Все сценарии используют только публичное API (scope, module, binding, scoping, async). ## Сценарии -- **RegisterAndResolve**: базовая операция регистрации и разрешения зависимости. -- **ChainSingleton (A->B->C, singleton)**: цепочка зависимостей, все singletons. -- **ChainFactory (A->B->C, factory)**: цепочка зависимостей с factory биндингами, новые объекты на каждый запрос. -- **NamedResolve (by name)**: разрешение именованной зависимости среди нескольких реализаций. +- **RegisterAndResolve**: базовая регистрация и разрешение зависимости. +- **ChainSingleton (A->B->C, singleton)**: длинная цепочка зависимостей, все как singleton. +- **ChainFactory (A->B->C, factory)**: цепочка зависимостей через factory (новый объект на каждый запрос). +- **NamedResolve (by name)**: разрешение зависимости по имени среди нескольких реализаций. - **AsyncChain (A->B->C, async)**: асинхронная цепочка зависимостей. -- **ScopeOverride (child overrides parent)**: переопределение зависимости в дочернем scope над родительским. +- **ScopeOverride (child overrides parent)**: перекрытие зависимости в дочернем scope относительно родителя. -## Результаты исследования +## Возможности -| Сценарий | RunTime (мкс) | -|----------------------------------------------------|--------------| -| RegisterAndResolve | 0.4574 | -| ChainSingleton (A->B->C, singleton) | 0.3759 | -| ChainFactory (A->B->C, factory) | 1.3783 | -| NamedResolve (by name) | 0.5193 | -| AsyncChain (A->B->C, async) | 0.5985 | -| ScopeOverride (child overrides parent) | 0.3611 | +- **Унифицированная структура бенчмарков**: Все тесты используют единый миксин для setup/teardown (`BenchmarkWithScope`). +- **Гибкая параметризация CLI**: + Любые комбинации параметров chainCount, nestingDepth, сценария и формата вывода. +- **Массовый/матричный запуск**: + Перебор всех вариантов комбинаций chainCount и depth одной командой. +- **Машино- и человекочитаемый вывод**: + Поддержка pretty-таблицы, CSV, JSON — удобно для анализа результатов. +- **Выбор сценария**: + Запуск всех сценариев или только нужного через CLI. -## Как запускать +## Как запустить -1. Получить зависимости: +1. Установить зависимости: ```shell dart pub get ``` -2. Запустить бенчмарк: +2. Запустить все бенчмарки с параметрами по умолчанию: ```shell dart run bin/main.dart ``` -Будет показан текстовый отчёт по всем метрикам. +### Запуск с параметрами + +- Матричный прогон (csv-вывод): + ```shell + dart run bin/main.dart --benchmark=chain_singleton --chainCount=10,100 --nestingDepth=5,10 --format=csv + ``` + +- Только сценарий разрешения по имени: + ```shell + dart run bin/main.dart --benchmark=named + ``` + +- Справка по командам: + ```shell + dart run bin/main.dart --help + ``` + +#### CLI-флаги + +- `--benchmark` (или `-b`) — Сценарий: + `register`, `chain_singleton`, `chain_factory`, `named`, `override`, `async_chain`, `all` (по умолчанию) +- `--chainCount` (или `-c`) — Через запятую, несколько длин цепочек. Например: `10,100` +- `--nestingDepth` (или `-d`) — Через запятую, глубины цепочек. Например: `5,10` +- `--format` (или `-f`) — Формат вывода: `pretty` (таблица), `csv`, `json` +- `--help` (или `-h`) — Показать справку + +#### Пример вывода (`--format=csv`) +``` +benchmark,chainCount,nestingDepth,elapsed_us +ChainSingleton,10,5,2450000 +ChainSingleton,10,10,2624000 +ChainSingleton,100,5,2506300 +ChainSingleton,100,10,2856900 +``` --- -Если хотите добавить свой сценарий — создайте отдельный Dart-файл и объявите новый BenchmarkBase/AsyncBenchmarkBase, не забудьте вставить его вызов в main. +## Добавить свой бенчмарк + +1. Создайте Dart-файл с классом, наследующим BenchmarkBase или AsyncBenchmarkBase. +2. Используйте миксин BenchmarkWithScope для автоматического управления Scope. +3. Добавьте его вызов в bin/main.dart для выбора через CLI. + +--- + +## Пример для контрибуторов + +```dart +class MyBenchmark extends BenchmarkBase with BenchmarkWithScope { + MyBenchmark() : super('My custom'); + @override void setup() => setupScope([MyModule()]); + @override void run() { scope.resolve(); } + @override void teardown() => teardownScope(); +} +``` + +--- + +## Лицензия + +MIT