feat(planning): explain and trace planning decisions
This commit is contained in:
1 parent
609b3dece9
commit
d7a13b0b1e
24 files changed
+6073
-342
No files matched your search
@@ -1,4 +1,9 @@
|
||||
import { planLeave, PlanningOutcome, PlanningRequest } from '../services/leave-planner.service';
|
||||
import {
|
||||
createPlanningCalculation,
|
||||
PlanningOutcome,
|
||||
PlanningRequest,
|
||||
PlanningTrace,
|
||||
} from '../services/leave-planner.service';
|
||||
|
||||
export interface BenchmarkScenario {
|
||||
name: string;
|
||||
@@ -9,12 +14,15 @@ export interface BenchmarkMeasurement {
|
||||
scenario: string;
|
||||
repetition: number;
|
||||
preparationMs: number;
|
||||
calculationMs: number;
|
||||
planningMs: number;
|
||||
traceDeliveryMs: number;
|
||||
wallMs: number;
|
||||
outcome: PlanningOutcome['kind'];
|
||||
lastCompletedStage?: string;
|
||||
placements: number;
|
||||
deterministic: boolean;
|
||||
traceStatus: PlanningTrace['status'] | 'not-produced';
|
||||
traceCandidates: number;
|
||||
}
|
||||
|
||||
const balance = (
|
||||
@@ -166,18 +174,35 @@ export async function runLeavePlannerBenchmark(repetitions = 1): Promise<Benchma
|
||||
const request = structuredClone(scenario.request);
|
||||
const preparationMs = performance.now() - preparationStart;
|
||||
const calculationStart = performance.now();
|
||||
const outcome = await planLeave(request);
|
||||
const calculationMs = performance.now() - calculationStart;
|
||||
const calculation = createPlanningCalculation(request);
|
||||
const outcome = await calculation.outcome;
|
||||
const planningMs = performance.now() - calculationStart;
|
||||
const traceStart = performance.now();
|
||||
const trace = await calculation.trace;
|
||||
const traceDeliveryMs = performance.now() - traceStart;
|
||||
const summary = resultSummary(outcome);
|
||||
const stable = JSON.stringify(outcome);
|
||||
measurements.push({
|
||||
scenario: scenario.name,
|
||||
repetition,
|
||||
preparationMs,
|
||||
calculationMs,
|
||||
wallMs: preparationMs + calculationMs,
|
||||
planningMs,
|
||||
traceDeliveryMs,
|
||||
wallMs: preparationMs + planningMs + traceDeliveryMs,
|
||||
...summary,
|
||||
deterministic: previous === undefined || previous === stable,
|
||||
traceStatus: trace?.status ?? 'not-produced',
|
||||
traceCandidates:
|
||||
trace?.phases.reduce(
|
||||
(total, phase) =>
|
||||
total +
|
||||
phase.decisions.reduce(
|
||||
(decisionTotal, decision) =>
|
||||
decisionTotal + decision.candidates.length,
|
||||
0,
|
||||
),
|
||||
0,
|
||||
) ?? 0,
|
||||
});
|
||||
previous = stable;
|
||||
}
|
||||
@@ -187,7 +212,7 @@ export async function runLeavePlannerBenchmark(repetitions = 1): Promise<Benchma
|
||||
|
||||
export function benchmarkReport(measurements: BenchmarkMeasurement[]): string {
|
||||
const header =
|
||||
'scenario\trepetition\tpreparation_ms\tcalculation_ms\twall_ms\toutcome\tlast_stage\tplacements\tdeterministic';
|
||||
'scenario\trepetition\tpreparation_ms\tplanning_ms\ttrace_delivery_ms\twall_ms\toutcome\tlast_stage\tplacements\tdeterministic\ttrace_status\ttrace_candidates';
|
||||
return [
|
||||
header,
|
||||
...measurements.map((item) =>
|
||||
@@ -195,12 +220,15 @@ export function benchmarkReport(measurements: BenchmarkMeasurement[]): string {
|
||||
item.scenario,
|
||||
item.repetition,
|
||||
item.preparationMs.toFixed(1),
|
||||
item.calculationMs.toFixed(1),
|
||||
item.planningMs.toFixed(1),
|
||||
item.traceDeliveryMs.toFixed(1),
|
||||
item.wallMs.toFixed(1),
|
||||
item.outcome,
|
||||
item.lastCompletedStage ?? '',
|
||||
item.placements,
|
||||
item.deterministic,
|
||||
item.traceStatus,
|
||||
item.traceCandidates,
|
||||
].join('\t'),
|
||||
),
|
||||
].join('\n');
|
||||
|
||||
Reference in new issue
Block a user