Initial Commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# bottleneck
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user