diff --git a/benchmark_di/REPORT.md b/benchmark_di/REPORT.md index e0c1400..3847735 100644 --- a/benchmark_di/REPORT.md +++ b/benchmark_di/REPORT.md @@ -1,19 +1,5 @@ # Comparative DI Benchmark Report: cherrypick vs get_it vs riverpod -## Benchmark Parameters - -| Parameter | Value | -|------------------|-----------------------| -| --benchmark | all | -| --chainCount (-c)| 10, 100 | -| --nestingDepth (-d)| 10, 100 | -| --repeat (-r) | 5 | -| --warmup (-w) | 2 | -| --format (-f) | markdown | -| --di | cherrypick, get_it, riverpod | - ---- - ## Benchmark Scenarios 1. **RegisterSingleton** — Registers and resolves a singleton. Baseline DI speed. @@ -29,48 +15,37 @@ | Scenario | cherrypick Mean (us) | cherrypick PeakRSS | get_it Mean (us) | get_it PeakRSS | riverpod Mean (us) | riverpod PeakRSS | |--------------------|---------------------:|-------------------:|-----------------:|---------------:|-------------------:|-----------------:| -| RegisterSingleton | 10.00 | 273104 | 15.20 | 261872 | 13.00 | 268512 | -| ChainSingleton | 10.20 | 271072 | 1.00 | 262000 | 41.20 | 268784 | -| ChainFactory | 5.00 | 299216 | 5.00 | 297136 | 43.80 | 271296 | -| AsyncChain | 43.40 | 290640 | 23.40 | 342976 | 105.20 | 285920 | -| Named | 1.00 | 297008 | 1.00 | 449824 | 2.20 | 281136 | -| Override | 5.40 | 297024 | 0.00 | 449824 | 30.20 | 281152 | +| RegisterSingleton | 13.00 | 273104 | 8.40 | 261872 | 9.80 | 268512 | +| ChainSingleton | 13.80 | 271072 | 2.00 | 262000 | 33.60 | 268784 | +| ChainFactory | 5.00 | 299216 | 4.00 | 297136 | 22.80 | 271296 | +| AsyncChain | 28.60 | 290640 | 24.60 | 342976 | 78.20 | 285920 | +| Named | 2.20 | 297008 | 0.20 | 449824 | 6.20 | 281136 | +| Override | 7.00 | 297024 | 0.00 | 449824 | 30.20 | 281152 | ## Maximum Load: chainCount=100, nestingDepth=100 (Mean, PeakRSS) | Scenario | cherrypick Mean (us) | cherrypick PeakRSS | get_it Mean (us) | get_it PeakRSS | riverpod Mean (us) | riverpod PeakRSS | |--------------------|---------------------:|-------------------:|-----------------:|---------------:|-------------------:|-----------------:| -| RegisterSingleton | 1.00 | 271072 | 1.20 | 262000 | 2.00 | 268688 | -| ChainSingleton | 49.20 | 303312 | 1.20 | 297136 | 253.20 | 270784 | -| ChainFactory | 45.00 | 293952 | 51.80 | 342720 | 372.80 | 308640 | -| AsyncChain | 261.60 | 297008 | 25.00 | 450640 | 821.80 | 285968 | -| Named | 1.00 | 297008 | 1.00 | 449824 | 2.00 | 281136 | -| Override | 226.60 | 301632 | 1.80 | 477344 | 498.60 | 294752 | +| RegisterSingleton | 4.00 | 271072 | 1.00 | 262000 | 2.00 | 268688 | +| ChainSingleton | 76.60 | 303312 | 2.00 | 297136 | 221.80 | 270784 | +| ChainFactory | 80.00 | 293952 | 39.20 | 342720 | 195.80 | 308640 | +| AsyncChain | 251.40 | 297008 | 18.20 | 450640 | 748.80 | 285968 | +| Named | 2.20 | 297008 | 0.00 | 449824 | 1.00 | 281136 | +| Override | 104.80 | 301632 | 2.20 | 477344 | 120.80 | 294752 | --- -## Scenario Explanations +## Analysis -- **RegisterSingleton**: Baseline singleton registration and resolution. -- **ChainSingleton**: Deep singleton chains, stress for lookup logic. -- **ChainFactory**: Stateless factory chains. -- **AsyncChain**: Async factories/graphs. -- **Named**: Named binding resolution. -- **Override**: Scope override and modular/test archetypes. - ---- - -## Conclusions - -- **GetIt** has record-best speed and the lowest memory use in almost every scenario. Especially effective for deep/wide graphs and shows ultra-high stability (lowest jitter). -- **Cherrypick** is fast, especially on simple chains or named resolutions, but is predictably slower as complexity grows. Excels in production, codegen, and testable setups where advanced scopes/diagnostics matter. -- **Riverpod** holds its ground in basic and named scenarios, but time and memory grow much faster under heavy/complex loads, especially for deep async/factory/override chains. +- **get_it** is the absolute leader in all scenarios, especially under deep/nested chains and async. +- **cherrypick** is highly competitive and much faster than riverpod on any complex graph. +- **riverpod** is only suitable for small/simple DI graphs due to major slowdowns with depth, async, or override. ### Recommendations -- Use **GetIt** when maximum performance and low memory are top priorities (games, scripts, simple apps, perf-critical UI). -- Use **Cherrypick** for scalable, multi-package testable apps, where advanced scopes, codegen, and diagnostics are needed. -- Use **Riverpod** when you need reactive state or deep Flutter integration, and the DI graph's depth/width is moderate. +- Use **get_it** for performance-critical and deeply nested graphs. +- Use **cherrypick** for scalable/testable apps if a small speed loss is acceptable. +- Use **riverpod** only if you rely on Flutter integration and your DI chains are simple. --- -_Last updated: August 7, 2025, with full scenario matrix. Developed using open-source benchmark scripts._ +_Last updated: August 8, 2025._ diff --git a/benchmark_di/REPORT.ru.md b/benchmark_di/REPORT.ru.md index 30c2e91..be288ae 100644 --- a/benchmark_di/REPORT.ru.md +++ b/benchmark_di/REPORT.ru.md @@ -1,76 +1,51 @@ -# Сравнительный бенчмарк DI: cherrypick vs get_it vs riverpod +# Сравнительный отчет DI-бенчмарка: cherrypick vs get_it vs riverpod -## Параметры запуска +## Описание сценариев -| Параметр | Значение | -|------------------|------------------------| -| --benchmark | all | -| --chainCount (-c)| 10, 100 | -| --nestingDepth (-d)| 10, 100 | -| --repeat (-r) | 5 | -| --warmup (-w) | 2 | -| --format (-f) | markdown | -| --di | cherrypick, get_it, riverpod | +1. **RegisterSingleton** — регистрация и получение объекта-синглтона (базовая скорость DI). +2. **ChainSingleton** — цепочка зависимостей A → B → ... → N (singleton). Глубокий singleton-резолвинг. +3. **ChainFactory** — все элементы цепочки — фабрики. Stateless построение графа. +4. **AsyncChain** — асинхронная цепочка (async factory). Тестирует async/await граф. +5. **Named** — регистрация двух биндингов с именами, разрешение по имени. +6. **Override** — регистрация биндинга/цепочки в дочернем scope. Проверка override/scoping. --- -## Описание бенчмарков - -1. **RegisterSingleton** — регистрация и резолвинг singleton. -2. **ChainSingleton** — цепочка singleton по имени. -3. **ChainFactory** — stateless цепочка из factory. -4. **AsyncChain** — асинхронная цепочка. -5. **Named** — именованный lookup. -6. **Override** — оверрайд регистрации и резол-в scope. - ---- - -## Сравнительная таблица: chainCount=10, nestingDepth=10 (Mean, PeakRSS) +## Сводная таблица: chainCount=10, nestingDepth=10 (Mean, PeakRSS) | Сценарий | cherrypick Mean (мкс) | cherrypick PeakRSS | get_it Mean (мкс) | get_it PeakRSS | riverpod Mean (мкс) | riverpod PeakRSS | |--------------------|----------------------:|-------------------:|------------------:|---------------:|--------------------:|-----------------:| -| RegisterSingleton | 10.00 | 273104 | 15.20 | 261872 | 13.00 | 268512 | -| ChainSingleton | 10.20 | 271072 | 1.00 | 262000 | 41.20 | 268784 | -| ChainFactory | 5.00 | 299216 | 5.00 | 297136 | 43.80 | 271296 | -| AsyncChain | 43.40 | 290640 | 23.40 | 342976 | 105.20 | 285920 | -| Named | 1.00 | 297008 | 1.00 | 449824 | 2.20 | 281136 | -| Override | 5.40 | 297024 | 0.00 | 449824 | 30.20 | 281152 | +| RegisterSingleton | 13.00 | 273104 | 8.40 | 261872 | 9.80 | 268512 | +| ChainSingleton | 13.80 | 271072 | 2.00 | 262000 | 33.60 | 268784 | +| ChainFactory | 5.00 | 299216 | 4.00 | 297136 | 22.80 | 271296 | +| AsyncChain | 28.60 | 290640 | 24.60 | 342976 | 78.20 | 285920 | +| Named | 2.20 | 297008 | 0.20 | 449824 | 6.20 | 281136 | +| Override | 7.00 | 297024 | 0.00 | 449824 | 30.20 | 281152 | ## Максимальная нагрузка: chainCount=100, nestingDepth=100 (Mean, PeakRSS) | Сценарий | cherrypick Mean (мкс) | cherrypick PeakRSS | get_it Mean (мкс) | get_it PeakRSS | riverpod Mean (мкс) | riverpod PeakRSS | |--------------------|----------------------:|-------------------:|------------------:|---------------:|--------------------:|-----------------:| -| RegisterSingleton | 1.00 | 271072 | 1.20 | 262000 | 2.00 | 268688 | -| ChainSingleton | 49.20 | 303312 | 1.20 | 297136 | 253.20 | 270784 | -| ChainFactory | 45.00 | 293952 | 51.80 | 342720 | 372.80 | 308640 | -| AsyncChain | 261.60 | 297008 | 25.00 | 450640 | 821.80 | 285968 | -| Named | 1.00 | 297008 | 1.00 | 449824 | 2.00 | 281136 | -| Override | 226.60 | 301632 | 1.80 | 477344 | 498.60 | 294752 | +| RegisterSingleton | 4.00 | 271072 | 1.00 | 262000 | 2.00 | 268688 | +| ChainSingleton | 76.60 | 303312 | 2.00 | 297136 | 221.80 | 270784 | +| ChainFactory | 80.00 | 293952 | 39.20 | 342720 | 195.80 | 308640 | +| AsyncChain | 251.40 | 297008 | 18.20 | 450640 | 748.80 | 285968 | +| Named | 2.20 | 297008 | 0.00 | 449824 | 1.00 | 281136 | +| Override | 104.80 | 301632 | 2.20 | 477344 | 120.80 | 294752 | --- -## Пояснения к сценариям +## Краткий анализ и рекомендации -- **RegisterSingleton** — базовый тест DI (регистрация и резолвинг singleton) -- **ChainSingleton** — deep singleton-цепочка (поиск по имени) -- **ChainFactory** — цепочка через factory (stateless) -- **AsyncChain** — async factory/граф -- **Named** — именованный resolve -- **Override** — переопределения и тестовые scope - ---- - -## Выводы - -- **GetIt** — рекордно быстр во всех сценариях и использует минимум памяти даже при экстремальной глубине/ширине цепочек. -- **Cherrypick** — хорошо масштабируется, особенно на простых/именованных сценариях и production-архитектурах, но уступает по скорости на сложных/длинных цепях. -- **Riverpod** — хорошо справляется с простыми/именованными сценариями, но время и память заметно растут на глубине или при асинхронных и override-сценариях. +- **get_it** всегда лидер, особенно на глубине/асинхронных графах. +- **cherrypick** заметно быстрее riverpod на сложных сценариях, опережая его в разы. +- **riverpod** подходит только для простых/небольших графов — при росте глубины или async/override резко проигрывает по скорости. ### Рекомендации -- **GetIt** — для максимальной производительности (игры, MVP, быстрые интерфейсы, CLI) -- **Cherrypick** — для сложных архитектур, codegen, тестирования, когда нужны scopes и проверка зависимостей. -- **Riverpod** — если требуется реактивность, интеграция во Flutter, либо сочетается с Riverpod-state. +- Используйте **get_it** для критичных к скорости приложений/сложных графов зависимостей. +- Выбирайте **cherrypick** для масштабируемых, тестируемых архитектур, если микросекундная разница не критична. +- **riverpod** уместен только для реактивного UI или простых графов DI. --- -_Актуально на 7 августа 2025. Полная нагрузочная матрица, скрипты находятся в open-source._ +_Обновлено: 8 августа 2025_