From 590a19baeeeb0fc08a3e75c67829e28afc2d5c83 Mon Sep 17 00:00:00 2001 From: Jack Lukic Date: Fri, 5 Jun 2026 12:28:39 -0400 Subject: [PATCH] Bench: Add clean-heap and forced-GC krausest update probes --- .../bench/tachometer/bench-krausest.js | 55 +++++++++++++++++++ .../tachometer/tachometer-ci-krausest.json | 8 ++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/packages/component/bench/tachometer/bench-krausest.js b/packages/component/bench/tachometer/bench-krausest.js index 042366dc2..b25f35312 100644 --- a/packages/component/bench/tachometer/bench-krausest.js +++ b/packages/component/bench/tachometer/bench-krausest.js @@ -206,6 +206,36 @@ function getRows(el) { return el.component.getRows(); } +/******************************* + Update (clean heap) + Same workload as update-10th-50 but run first, before the + create-heavy ops, so the measured region starts on a clean heap. + The delta against update-10th-50 isolates suite-ordering GC cost. +*******************************/ + +// Warm render / reconcile / update so the first-op cold JIT doesn't +// skew the isolated measure. +const elWarm = await mount(); +elWarm.component.run(1000); +await flush(); +for (let i = 0; i < 10; i++) { + elWarm.component.update(); + flushWork(); +} +destroy(); + +const elIso = await mount(); +elIso.component.run(1000); +await flush(); +// purpose: Same update workload as update-10th-50 but on a clean heap with no create-heavy ops before it. Pairs with update-10th-50 to isolate suite-ordering GC pressure. +performance.mark(startMark('update-isolated-50')); +for (let i = 0; i < 50; i++) { + elIso.component.update(); + flushWork(); +} +performance.measure('update-isolated-50', startMark('update-isolated-50')); +destroy(); + /******************************* Create (krausest 01_run, 02b_runlots) @@ -279,6 +309,31 @@ for (let i = 0; i < 50; i++) { performance.measure('update-10th-50', startMark('update-10th-50')); destroy(); +/******************************* + Update (forced GC) + update-10th workload with a full GC before the measured region. + If the update-10th-50 delta vanishes here, the carried-in cost is + reclaimable GC pressure from the create-heavy ops above. +*******************************/ + +const el5b = await mount(); +el5b.component.run(1000); +await flush(); +// gc() exists only under --js-flags=--expose-gc (set in tachometer-ci-krausest.json). +// Settle after collecting so the measured region starts on a post-GC heap. +if (globalThis.gc) { + globalThis.gc(); + await flush(); +} +// purpose: update-10th workload with a forced GC before the measured region. If the update-10th-50 regression vanishes here it is reclaimable GC pressure. +performance.mark(startMark('update-gc-50')); +for (let i = 0; i < 50; i++) { + el5b.component.update(); + flushWork(); +} +performance.measure('update-gc-50', startMark('update-gc-50')); +destroy(); + /******************************* Select (krausest 05_select) diff --git a/packages/component/bench/tachometer/tachometer-ci-krausest.json b/packages/component/bench/tachometer/tachometer-ci-krausest.json index 1831aa38e..98cef950d 100644 --- a/packages/component/bench/tachometer/tachometer-ci-krausest.json +++ b/packages/component/bench/tachometer/tachometer-ci-krausest.json @@ -8,13 +8,15 @@ { "name": "this-change", "url": "ci-current-krausest.html", - "browser": { "name": "chrome", "headless": true }, + "browser": { "name": "chrome", "headless": true, "addArguments": ["--js-flags=--expose-gc"] }, "measurement": [ { "mode": "performance", "entryName": "create-1k" }, { "mode": "performance", "entryName": "create-10k" }, { "mode": "performance", "entryName": "replace-1k" }, { "mode": "performance", "entryName": "append-1k" }, { "mode": "performance", "entryName": "update-10th-50" }, + { "mode": "performance", "entryName": "update-isolated-50" }, + { "mode": "performance", "entryName": "update-gc-50" }, { "mode": "performance", "entryName": "select-40" }, { "mode": "performance", "entryName": "swap-rows-20" }, { "mode": "performance", "entryName": "remove-row-front-20" }, @@ -26,13 +28,15 @@ { "name": "tip-of-tree", "url": "ci-baseline-krausest.html", - "browser": { "name": "chrome", "headless": true }, + "browser": { "name": "chrome", "headless": true, "addArguments": ["--js-flags=--expose-gc"] }, "measurement": [ { "mode": "performance", "entryName": "create-1k" }, { "mode": "performance", "entryName": "create-10k" }, { "mode": "performance", "entryName": "replace-1k" }, { "mode": "performance", "entryName": "append-1k" }, { "mode": "performance", "entryName": "update-10th-50" }, + { "mode": "performance", "entryName": "update-isolated-50" }, + { "mode": "performance", "entryName": "update-gc-50" }, { "mode": "performance", "entryName": "select-40" }, { "mode": "performance", "entryName": "swap-rows-20" }, { "mode": "performance", "entryName": "remove-row-front-20" },