docs(benchmarks): update README files with new CLI, matrix run, output formats, and usage instructions (EN+RU)

This commit is contained in:
Sergey Penkovsky
2025-08-06 13:35:39 +03:00
parent 926bbf15f4
commit 7f488f873e
2 changed files with 155 additions and 41 deletions

View File

@@ -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<MyType>(); }
@override void teardown() => teardownScope();
}
```
---
## License
MIT

View File

@@ -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<MyType>(); }
@override void teardown() => teardownScope();
}
```
---
## Лицензия
MIT