mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Use paired ABBA/BAAB batches for the p95 gate and accept the complete 104-frame Linux golden artifact. The four new #276 scenes were visually reviewed; every existing scene passed, and the nine byte changes contain zero pixels above their comparison threshold. Issue: #276 User-Visible: no Release: v1.67.0-beta.8 Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/32684802336
93 lines
3.4 KiB
JavaScript
93 lines
3.4 KiB
JavaScript
// #276: same-process incremental cost of coincident-partition reconciliation
|
|
// inside the complete Optimize candidate pass on the deterministic large house.
|
|
import { performance } from 'node:perf_hooks';
|
|
|
|
import { makeLargeHouseFixture, LARGE_HOUSE_COUNTS } from './fixtures/large-house.mjs';
|
|
import { optimizePlans } from '../test-build/plan-optimizer.js';
|
|
|
|
const WARMUPS = 5;
|
|
const SAMPLES = 20;
|
|
const BATCH_SIZE = 10;
|
|
const RELATIVE_OVERHEAD = 0.15;
|
|
const ABSOLUTE_OVERHEAD_MS = 25;
|
|
|
|
const fixture = makeLargeHouseFixture();
|
|
const emptyReconciliation = (rawSpace, _model, walls) => ({
|
|
walls: walls || [],
|
|
partitions: Array.isArray(rawSpace?.partitions) ? rawSpace.partitions : [],
|
|
openings: Array.isArray(rawSpace?.openings) ? rawSpace.openings : [],
|
|
partitionsReconciled: 0,
|
|
openingsRehosted: 0,
|
|
});
|
|
const baseline = () => optimizePlans(fixture.config, {}, {}, {
|
|
reconcileCoincidentPartitions: emptyReconciliation,
|
|
});
|
|
const candidate = () => optimizePlans(fixture.config, {});
|
|
const timed = (operation) => {
|
|
const start = performance.now();
|
|
for (let index = 0; index < BATCH_SIZE; index++) {
|
|
const result = operation();
|
|
if (!result || !result.report) throw new Error('Optimize candidate returned no report');
|
|
}
|
|
return (performance.now() - start) / BATCH_SIZE;
|
|
};
|
|
for (let index = 0; index < WARMUPS; index++) {
|
|
baseline();
|
|
candidate();
|
|
}
|
|
|
|
const baselineTimes = [];
|
|
const candidateTimes = [];
|
|
const overheadTimes = [];
|
|
for (let index = 0; index < SAMPLES; index++) {
|
|
// ABBA/BAAB cancels first-order clock drift and balances cache/GC order;
|
|
// batching then averages timer noise before the paired p95 is computed.
|
|
const candidateFirst = index % 2 === 1;
|
|
const first = timed(candidateFirst ? candidate : baseline);
|
|
const second = timed(candidateFirst ? baseline : candidate);
|
|
const third = timed(candidateFirst ? baseline : candidate);
|
|
const fourth = timed(candidateFirst ? candidate : baseline);
|
|
const baselineMs = candidateFirst ? (second + third) / 2 : (first + fourth) / 2;
|
|
const candidateMs = candidateFirst ? (first + fourth) / 2 : (second + third) / 2;
|
|
baselineTimes.push(baselineMs);
|
|
candidateTimes.push(candidateMs);
|
|
overheadTimes.push(candidateMs - baselineMs);
|
|
}
|
|
|
|
const quantile = (values, ratio) => {
|
|
const sorted = [...values].sort((a, b) => a - b);
|
|
return sorted[Math.min(sorted.length - 1, Math.ceil(sorted.length * ratio) - 1)];
|
|
};
|
|
const summary = (values) => ({
|
|
min: Math.min(...values),
|
|
median: quantile(values, 0.5),
|
|
p95: quantile(values, 0.95),
|
|
max: Math.max(...values),
|
|
});
|
|
const baselineSummary = summary(baselineTimes);
|
|
const candidateSummary = summary(candidateTimes);
|
|
const overheadSummary = summary(overheadTimes);
|
|
const measuredOverheadP95 = Math.max(0, overheadSummary.p95);
|
|
const relativeP95 = measuredOverheadP95
|
|
/ Math.max(baselineSummary.p95, Number.EPSILON);
|
|
const pass = measuredOverheadP95 <= ABSOLUTE_OVERHEAD_MS
|
|
&& relativeP95 <= RELATIVE_OVERHEAD;
|
|
const report = {
|
|
issue: 276,
|
|
fixture: LARGE_HOUSE_COUNTS,
|
|
warmups: WARMUPS,
|
|
samples: SAMPLES,
|
|
batchSize: BATCH_SIZE,
|
|
baseline: baselineSummary,
|
|
candidate: candidateSummary,
|
|
pairedOverhead: overheadSummary,
|
|
budgets: {
|
|
relativeOverhead: RELATIVE_OVERHEAD,
|
|
absoluteOverheadMs: ABSOLUTE_OVERHEAD_MS,
|
|
},
|
|
measured: { overheadP95Ms: measuredOverheadP95, relativeP95 },
|
|
pass,
|
|
};
|
|
console.log(JSON.stringify(report, null, 2));
|
|
if (!pass) process.exitCode = 1;
|