# bottleneck _(no submodules)_ ## Purpose `BottleneckDetector` analyses arrays of `ProfileEntry` records to surface performance bottlenecks. It groups entries by label, computes per-group average duration and frequency, and ranks results by impact (`avgDuration * frequency`). Detection is pure and stateless — the same detector can be applied to entries from any `Profiler` instance without coupling. ## Features - Zod-validated configuration (`timeBudgetMs > 0`, `hotSpotFrequency > 0`, `maxResults > 0`). - `analyze(entries)` — returns up to `maxResults` bottlenecks with attached `suggestion` strings, ranked by impact descending. - `findBudgetViolations(entries)` — returns every entry whose `duration` exceeds `timeBudgetMs`. - `findHotSpots(entries)` — returns entries that are BOTH slower than budget AND occur at least `hotSpotFrequency` times. - Suggestion tiering: hot-spot, massively-over-budget (>10x), over-budget, and very-frequent thresholds each produce a distinct human-readable hint. ## Usage: Basic ```ts import { BottleneckDetector } from "@suaveplan/profiler"; const detector = new BottleneckDetector({ timeBudgetMs: 16 }); const bottlenecks = detector.analyze(profiler.getEntries()); for (const b of bottlenecks) { console.warn(b.suggestion); } ``` ## Usage: Advanced ```ts import { BottleneckDetector } from "@suaveplan/profiler"; const detector = new BottleneckDetector({ timeBudgetMs: 4, // sub-frame budget for 240Hz displays hotSpotFrequency: 50, maxResults: 5, }); const violations = detector.findBudgetViolations(profiler.getEntries()); const hotSpots = detector.findHotSpots(profiler.getEntries()); if (hotSpots.length > 0) { metrics.bottlenecks.add(hotSpots.length, { tier: "hot-spot" }); } ``` ## API Reference - `class BottleneckDetector` — `new BottleneckDetector(config?: BottleneckConfig)`. - `interface BottleneckConfig { timeBudgetMs?, hotSpotFrequency?, maxResults? }`. - Methods: `analyze`, `findBudgetViolations`, `findHotSpots`. - Errors: `ProfilerError` with `PROFILER.INVALID_OPTIONS` on bad config. ## Implementation Notes `analyze` filters out entries with `duration === undefined` (still-running measurements), groups by label, and dispatches to `generateSuggestion`. The suggestion tiers are checked in priority order so a hot-spot label takes precedence over the massive-over-budget tier even when both apply, and the very-frequent tier only fires when an entry is cheap-but-noisy. Sort is stable and deterministic — equal impacts retain insertion order, which keeps the output reproducible across runs.