From 6b4df6499f8dac600a29199aa75e926630c85023 Mon Sep 17 00:00:00 2001 From: leo-gan Date: Tue, 1 Sep 2026 17:01:00 -0700 Subject: [PATCH] fix(dashboard): size labels, closed experiment explainer, queue copy Compare payload-size options say compounded data sizes and offer both sizes at 100 items and at 1000 items. The experiment explainer stays closed until opened and describes queues, not serializers. Experiment 13 no longer mentions five leftover data-type names. --- dashboard/experiments.css | 5 +++ dashboard/experiments.js | 41 +++++++++--------- dashboard/main.js | 22 +++++----- .../experiments/13-payload-size-sweep.json.gz | Bin 8511 -> 8509 bytes dashboard/public/data/experiments/index.json | 6 +-- experiments/13-payload-size-sweep/README.md | 12 +++-- .../13-payload-size-sweep/experiment.yaml | 9 ++-- .../13-payload-size-sweep/results.json | 2 +- experiments/13-payload-size-sweep/results.md | 6 +-- .../13-payload-size-sweep/summarize.py | 21 ++++----- 10 files changed, 62 insertions(+), 62 deletions(-) diff --git a/dashboard/experiments.css b/dashboard/experiments.css index 5bf517e..97cc008 100644 --- a/dashboard/experiments.css +++ b/dashboard/experiments.css @@ -49,6 +49,11 @@ body.dash-view-experiments #filter-policy-meta { margin: 0.5rem 0 0; } +.exp-why[open] { + max-height: min(28rem, 55vh); + overflow: auto; +} + .exp-story p { margin: 0.35rem 0; } diff --git a/dashboard/experiments.js b/dashboard/experiments.js index 23edf1f..ae71f80 100644 --- a/dashboard/experiments.js +++ b/dashboard/experiments.js @@ -244,43 +244,44 @@ function selectHtml(id, label, values, current, labelFn) { function renderWhyExperiments() { return ` -
+
Why experiments, if the Dashboard already has every number?

- The main Dashboard is the full warehouse: every library, every record shape. - That is the right place to browse. It is the wrong place to pick a library for a real service - by sorting on speed. + The main Dashboard is the full warehouse: every library, every payload size, + every pattern. That is the right place to browse. It is the wrong place to pick a queue + for a real service by sorting on speed.

- The fastest row in the big table may be a library you cannot use. - It might write bytes that only one language can read. - It might drop field names so partners cannot parse the text. - It might be built for a file you write once, not for a web request you write on every click. - The Dashboard will still put it first, because it is fast. + The fastest row in the big table may be a queue you cannot use. + It might only work with one writer and one reader. It might be an async queue + while your workers are operating-system threads. It might be a scheduler that + does not hand a payload from a producer to a consumer. The Dashboard will still + put it first, because it is fast on that slice.

An experiment starts with a decision, not a sort. - Example: “We must keep JSON on the public website. Which JSON library is fast enough?” - We keep only the libraries that could be the answer. We time one shared record. + Example: “One request thread puts work; one worker takes it. The ticket is + 256 bytes. Which in-process queue is fast enough?” + We keep only the libraries that could be the answer. We time one shared payload. We write down what we would give up.

- Think of a grocery store and a recipe. The store has every product — that is the main Dashboard. - The recipe lists only what you need for dinner, and why — that is an experiment. - You need both. The store does not tell you what to cook. + Think of a grocery store and a recipe. The store has every product — that is the + main Dashboard. The recipe lists only what you need for dinner, and why — that + is an experiment. You need both. The store does not tell you what to cook.

Concrete traps the big table does not prevent:

    -
  • Different jobs in one list. JSON, compact bytes, and a Python-only format can share a table. “What is fastest?” is not one question.
  • -
  • A tiny gap looks like a winner. 1.7 µs vs 1.8 µs is not a reason to rewrite a service.
  • -
  • Your constraint is invisible. If browsers must keep JSON, the big table still shows every format.
  • -
  • One record is not one hundred. The winner at 1 can lose at 100.
  • -
  • Numbers without a story. “Binary is faster” is how teams break a public website.
  • +
  • Different jobs in one list. A 1P1C ring and a 4P4C channel can share a table. “What is fastest?” is not one question.
  • +
  • A tiny gap looks like a winner. A few percent is not a reason to rewrite a service.
  • +
  • Your constraint is invisible. If you must use threads, the big table still shows async queues.
  • +
  • One size is not another. The winner at 256 bytes can lose at 4 KiB.
  • +
  • One pattern is not another. The winner at 1P1C can lose at 4P4C.

- We do not run a second benchmark. We cut the same numbers down to a fair contest + We do not run a second clock. We cut the same numbers down to a fair contest and put the story next to them. Longer notes

diff --git a/dashboard/main.js b/dashboard/main.js index 93ac787..1a14d14 100644 --- a/dashboard/main.js +++ b/dashboard/main.js @@ -1878,7 +1878,7 @@ function populateDataTypeSelect(options, cfg = {}) { batchCompound.forEach(addOpt); } if (allTypes.length) { - addSep('── compounded data types ──'); + addSep('── compounded data sizes ──'); allTypes.forEach(addOpt); } if (allAll.length) { @@ -2231,20 +2231,20 @@ function discoverDataTypeOptions(allGroups) { } batchCompound.sort(); - // Cross-type at fixed n + // Both published sizes at one item count: all@100, all@1000. const allTypes = []; - if (nsGlobal.has(1)) allTypes.push('all@1'); - if (nsGlobal.has(100)) allTypes.push('all@100'); - - // Everything - const allAll = natural.length ? ['all@all'] : []; + if (byBase.size >= 2) { + for (const n of [...nsGlobal].sort((a, b) => a - b)) { + allTypes.push(`all@${n}`); + } + } return { natural, batchCompound, allTypes, - allAll, - all: [...natural, ...batchCompound, ...allTypes, ...allAll], + allAll: [], + all: [...natural, ...batchCompound, ...allTypes], }; } @@ -3420,7 +3420,7 @@ function renderTable() { scopeNote = ` Compounded batch: mean of ${escapeHtml(scope.base)}@n=${scope.nA} and ${escapeHtml(scope.base)}@n=${scope.nB}.`; } else if (scope.kind === 'all_n') { - scopeNote = ` Compounded data types at n=${scope.n}.`; + scopeNote = ` Both sizes at ${scope.n} items.`; } else if (scope.kind === 'all_all') { scopeNote = ` Compounded all (all@all).`; } @@ -3730,7 +3730,7 @@ function copyRosterMarkdown() { return `Scope: compounded batch ${state.currentTestData} · mode ${state.currentMode}`; } if (s.kind === 'all_n') { - return `Scope: all data types @ n=${s.n} · mode ${state.currentMode}`; + return `Scope: both sizes · ${s.n} items · ${modeDisplayLabel(normalizeMode(state.currentMode))}`; } if (s.kind === 'all_all') { return `Scope: all@all (all types × all n) · mode ${state.currentMode}`; diff --git a/dashboard/public/data/experiments/13-payload-size-sweep.json.gz b/dashboard/public/data/experiments/13-payload-size-sweep.json.gz index a1c1b96795fe41e9b2501c3863ee8c831ac961b8..9848938419cb51d481c56838c13b6a90e7da6945 100644 GIT binary patch delta 8424 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 KD5KYx=>Pyl!b{@- delta 8426 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 diff --git a/dashboard/public/data/experiments/index.json b/dashboard/public/data/experiments/index.json index 63c0028..0f71201 100644 --- a/dashboard/public/data/experiments/index.json +++ b/dashboard/public/data/experiments/index.json @@ -1,6 +1,6 @@ { "schema": "gld.dashboard.experiments/1", - "generated_at": "2026-09-01T22:23:00Z", + "generated_at": "2026-09-02T00:00:42Z", "count": 13, "with_results": 13, "experiments": [ @@ -598,9 +598,9 @@ "number": 13, "slug": "payload-size-sweep", "title": "Which payload sizes change the ranking?", - "question": "Same SPSC handoff, five payload sizes (1 B, 64 B, 256 B, 4 KiB, 64 KiB). Which sizes produce a different ranking, and which are just more of the same?\n", + "question": "Same 1P1C handoff, five payload sizes (1 B, 64 B, 256 B, 4 KiB, 64 KiB). Which sizes produce a different ranking, and which are just more of the same?\n", "story": { - "why": "The default suite names five data types, but every runner builds an opaque byte string of a chosen length. If ranking only moves at a couple of lengths, the published matrix should keep those lengths and drop the rest.\n", + "why": "Every runner builds an opaque byte string of a chosen length. If ranking only moves at a couple of lengths, the published matrix should keep those lengths and drop the rest.\n", "example": "A ticket is a few hundred bytes. An HTTP body is a few kilobytes. A file chunk can be tens of kilobytes. We need to know which of those worlds actually changes which queue wins.\n", "tradeoff": "Extra sizes cost machine time and make the dashboard harder to read. One size is enough if copy cost never changes the order. Two sizes are enough if a small payload and a large payload tell different stories.\n" }, diff --git a/experiments/13-payload-size-sweep/README.md b/experiments/13-payload-size-sweep/README.md index 20c62b7..b5ef423 100644 --- a/experiments/13-payload-size-sweep/README.md +++ b/experiments/13-payload-size-sweep/README.md @@ -1,16 +1,14 @@ # 13 — Payload size sweep -**Question:** which payload sizes change the SPSC ranking, and which are +**Question:** which payload sizes change the 1P1C ranking, and which are redundant? -This is not another named data type. Every runner already builds an opaque -byte string. The five catalog names (`message`, `event`, `telemetry`, -`strings`, `document`) are five lengths between 256 B and 4 KiB. This -folder asks whether the published suite needs those names at all, or only -one or two lengths. +Every runner already builds an opaque byte string of a chosen length. +This folder asked which lengths change ranking, and which are just more +of the same. Sizes in this run: **1 B, 64 B, 256 B, 4 KiB, 64 KiB**. One hundred items -per repetition. SPSC only. One hundred repetitions (`full`). +per repetition. 1P1C only. One hundred repetitions (`full`). ```bash ./experiments/13-payload-size-sweep/run.sh python diff --git a/experiments/13-payload-size-sweep/experiment.yaml b/experiments/13-payload-size-sweep/experiment.yaml index 11a21f6..774e515 100644 --- a/experiments/13-payload-size-sweep/experiment.yaml +++ b/experiments/13-payload-size-sweep/experiment.yaml @@ -2,15 +2,14 @@ schema: gld.experiment.config/1 id: 13-payload-size-sweep title: Which payload sizes change the ranking? question: > - Same SPSC handoff, five payload sizes (1 B, 64 B, 256 B, 4 KiB, 64 KiB). + Same 1P1C handoff, five payload sizes (1 B, 64 B, 256 B, 4 KiB, 64 KiB). Which sizes produce a different ranking, and which are just more of the same? story: why: > - The default suite names five data types, but every runner builds an - opaque byte string of a chosen length. If ranking only moves at a - couple of lengths, the published matrix should keep those lengths and - drop the rest. + Every runner builds an opaque byte string of a chosen length. If ranking + only moves at a couple of lengths, the published matrix should keep those + lengths and drop the rest. example: > A ticket is a few hundred bytes. An HTTP body is a few kilobytes. A file chunk can be tens of kilobytes. We need to know which of those diff --git a/experiments/13-payload-size-sweep/results.json b/experiments/13-payload-size-sweep/results.json index 821227a..ace25ee 100644 --- a/experiments/13-payload-size-sweep/results.json +++ b/experiments/13-payload-size-sweep/results.json @@ -1,6 +1,6 @@ { "generated_at": "2026-09-01T22:23:00Z", - "question": "Which SPSC payload sizes change the ranking?", + "question": "Which 1P1C payload sizes change the ranking?", "sizes_bytes": [ 1, 64, diff --git a/experiments/13-payload-size-sweep/results.md b/experiments/13-payload-size-sweep/results.md index 17671fd..c1c7a2f 100644 --- a/experiments/13-payload-size-sweep/results.md +++ b/experiments/13-payload-size-sweep/results.md @@ -2,7 +2,7 @@ Times are not comparable across languages. -Question: which SPSC payload sizes change the ranking? +Question: which 1P1C payload sizes change the ranking? ## Recommendation @@ -24,9 +24,9 @@ Do not confuse **payload bytes per item** with **how many items** move in one re - `size_1` (1 B): same first place as 256 B, no copy-bound pack collapse, no inversion. - `size_64` (64 B): same first place as 256 B, no copy-bound pack collapse, no inversion. -## What this means for the named types +## What this means for the published matrix -The published catalog names `message`, `event`, `telemetry`, `strings`, and `document` are already five lengths: 256 B, 512 B, 1 KiB, 2 KiB, and 4 KiB. Runners do not serialize those object graphs. The warehouse SPSC ranks on those names match this sweep: Python and C never change first place; JavaScript and C# only shuffle a mid-pack pair; Rust first becomes copy-bound at 4 KiB. 512 B, 1 KiB, and 2 KiB do not add a ranking question. Keep `message` (256 B) and `document` (4 KiB). Drop the three names in between from the default matrix when that change is applied. +Every runner builds an opaque byte string. This sweep asked which lengths change 1P1C ranking. Python and C never change first place. JavaScript and C# only shuffle a close pair. Rust first changes at 4 KiB, when the queue copies every byte. Keep 256 B and 4 KiB on the default matrix. 1 B and 64 B match 256 B. 64 KiB is a later research cell, not a third published size. ## Per language vs 256 B diff --git a/experiments/13-payload-size-sweep/summarize.py b/experiments/13-payload-size-sweep/summarize.py index 856314a..2f636ab 100755 --- a/experiments/13-payload-size-sweep/summarize.py +++ b/experiments/13-payload-size-sweep/summarize.py @@ -371,7 +371,7 @@ def write_combined_md( "", "Times are not comparable across languages.", "", - "Question: which SPSC payload sizes change the ranking?", + "Question: which 1P1C payload sizes change the ranking?", "", "## Recommendation", "", @@ -408,17 +408,14 @@ def write_combined_md( lines.append("") lines.extend( [ - "## What this means for the named types", + "## What this means for the published matrix", "", - "The published catalog names `message`, `event`, `telemetry`, " - "`strings`, and `document` are already five lengths: 256 B, 512 B, " - "1 KiB, 2 KiB, and 4 KiB. Runners do not serialize those object " - "graphs. The warehouse SPSC ranks on those names match this sweep: " - "Python and C never change first place; JavaScript and C# only " - "shuffle a mid-pack pair; Rust first becomes copy-bound at 4 KiB. " - "512 B, 1 KiB, and 2 KiB do not add a ranking question. Keep " - "`message` (256 B) and `document` (4 KiB). Drop the three names " - "in between from the default matrix when that change is applied.", + "Every runner builds an opaque byte string. This sweep asked which " + "lengths change 1P1C ranking. Python and C never change first " + "place. JavaScript and C# only shuffle a close pair. Rust first " + "changes at 4 KiB, when the queue copies every byte. Keep 256 B " + "and 4 KiB on the default matrix. 1 B and 64 B match 256 B. " + "64 KiB is a later research cell, not a third published size.", "", "## Per language vs 256 B", "", @@ -470,7 +467,7 @@ def main() -> int: recommendation = recommend(lang_reports) payload = { "generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), - "question": "Which SPSC payload sizes change the ranking?", + "question": "Which 1P1C payload sizes change the ranking?", "sizes_bytes": [SIZE_BYTES[t] for t in SIZE_ORDER], "baseline_bytes": SIZE_BYTES[BASELINE], "recommendation": recommendation,