From 0ffed1cd351558ff8b73a94a5fc4eb08891eb34d Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Tue, 29 Jul 2025 15:09:09 +0200 Subject: [PATCH 1/5] Simplify updateUiAfterRun --- JetStreamDriver.js | 157 +++++++++++---------------------------------- 1 file changed, 36 insertions(+), 121 deletions(-) diff --git a/JetStreamDriver.js b/JetStreamDriver.js index 7e0eb620..c6e8537c 100644 --- a/JetStreamDriver.js +++ b/JetStreamDriver.js @@ -126,21 +126,6 @@ function assert(b, m = "") { throw new Error(`Bad assertion: ${m}`); } -function firstID(benchmark) { - return `results-cell-${benchmark.name}-first`; -} - -function worst4ID(benchmark) { - return `results-cell-${benchmark.name}-worst4`; -} - -function avgID(benchmark) { - return `results-cell-${benchmark.name}-avg`; -} - -function scoreID(benchmark) { - return `results-cell-${benchmark.name}-score`; -} function mean(values) { assert(values instanceof Array); @@ -679,9 +664,20 @@ class Benchmark { } get score() { + const subScores = Object.values(this.subScores()); + return geomean(subScores); + } + + subScores() { throw new Error("Subclasses need to implement this"); } + allScores() { + const allScores = this.subScores(); + allScores["score"] = this.score; + return allScores; + } + get prerunCode() { return null; } get preIterationCode() { @@ -993,7 +989,14 @@ class Benchmark { this.preloads = Object.entries(this.plan.preload ?? {}); } - scoreIdentifiers() { throw new Error("Must be implemented by subclasses"); } + scoreIdentifiers() { + const ids = Object.keys(this.allScores()).map(name => this.scoreIdentifier(name)); + return ids; + } + + scoreIdentifier(name) { + return `results-cell-${this.name}-${name}`; + } updateUIBeforeRun() { if (!isInBrowser) { @@ -1019,6 +1022,23 @@ class Benchmark { benchmarkResultsUI.classList.remove("benchmark-running"); benchmarkResultsUI.classList.add("benchmark-done"); + const scoreEntries = Object.entries(this.allScores()); + if (isInBrowser) { + for (const [name, value] of scoreEntries) + document.getElementById(this.scoreIdentifier(name)).innerHTML = uiFriendlyScore(value); + } + + if (dumpJSONResults) + return; + + console.log(this.name); + for (const [name, value] of scoreEntries) + console.log(` ${name}:`, uiFriendlyScore(value)); + if (RAMification) { + console.log(" Current Footprint:", uiFriendlyNumber(this.currentFootprint)); + console.log(" Peak Footprint:", uiFriendlyNumber(this.peakFootprint)); + } + console.log(" Wall time:", uiFriendlyDuration(this.endTime - this.startTime)); } }; @@ -1063,10 +1083,6 @@ class DefaultBenchmark extends Benchmark { this.averageScore = toScore(this.averageTime); } - get score() { - return geomean([this.firstIterationScore, this.worst4Score, this.averageScore]); - } - subScores() { return { "First": this.firstIterationScore, @@ -1074,35 +1090,6 @@ class DefaultBenchmark extends Benchmark { "Average": this.averageScore, }; } - - scoreIdentifiers() { - return [firstID(this), worst4ID(this), avgID(this), scoreID(this)]; - } - - updateUIAfterRun() { - super.updateUIAfterRun(); - - if (isInBrowser) { - document.getElementById(firstID(this)).innerHTML = uiFriendlyScore(this.firstIterationScore); - document.getElementById(worst4ID(this)).innerHTML = uiFriendlyScore(this.worst4Score); - document.getElementById(avgID(this)).innerHTML = uiFriendlyScore(this.averageScore); - document.getElementById(scoreID(this)).innerHTML = uiFriendlyScore(this.score); - return; - } - - if (dumpJSONResults) - return; - - console.log(" Startup:", uiFriendlyScore(this.firstIterationScore)); - console.log(" Worst Case:", uiFriendlyScore(this.worst4Score)); - console.log(" Average:", uiFriendlyScore(this.averageScore)); - console.log(" Score:", uiFriendlyScore(this.score)); - if (RAMification) { - console.log(" Current Footprint:", uiFriendlyNumber(this.currentFootprint)); - console.log(" Peak Footprint:", uiFriendlyNumber(this.peakFootprint)); - } - console.log(" Wall time:", uiFriendlyDuration(this.endTime - this.startTime)); - } } class AsyncBenchmark extends DefaultBenchmark { @@ -1250,10 +1237,6 @@ class WSLBenchmark extends Benchmark { this.mainRunScore = toScore(results[1]); } - get score() { - return geomean([this.stdlibScore, this.mainRunScore]); - } - get runnerCode() { return ` let benchmark = new Benchmark(); @@ -1292,33 +1275,6 @@ class WSLBenchmark extends Benchmark { "MainRun": this.mainRunScore, }; } - - scoreIdentifiers() { - return ["wsl-stdlib-score", "wsl-tests-score", "wsl-score-score"]; - } - - updateUIAfterRun() { - super.updateUIAfterRun(); - - if (isInBrowser) { - document.getElementById("wsl-stdlib-score").innerHTML = uiFriendlyScore(this.stdlibScore); - document.getElementById("wsl-tests-score").innerHTML = uiFriendlyScore(this.mainRunScore); - document.getElementById("wsl-score-score").innerHTML = uiFriendlyScore(this.score); - return; - } - - if (dumpJSONResults) - return; - - console.log(" Stdlib:", uiFriendlyScore(this.stdlibScore)); - console.log(" Tests:", uiFriendlyScore(this.mainRunScore)); - console.log(" Score:", uiFriendlyScore(this.score)); - if (RAMification) { - console.log(" Current Footprint:", uiFriendlyNumber(this.currentFootprint)); - console.log(" Peak Footprint:", uiFriendlyNumber(this.peakFootprint)); - } - console.log(" Wall time:", uiFriendlyDuration(this.endTime - this.startTime)); - } }; class WasmLegacyBenchmark extends Benchmark { @@ -1338,10 +1294,6 @@ class WasmLegacyBenchmark extends Benchmark { this.runScore = toScore(results[1]); } - get score() { - return geomean([this.startupScore, this.runScore]); - } - get prerunCode() { const str = ` let verbose = false; @@ -1464,43 +1416,6 @@ class WasmLegacyBenchmark extends Benchmark { "Runtime": this.runScore, }; } - - get startupID() { - return `wasm-startup-id${this.name}`; - } - get runID() { - return `wasm-run-id${this.name}`; - } - get scoreID() { - return `wasm-score-id${this.name}`; - } - - scoreIdentifiers() { - return [this.startupID, this.runID, this.scoreID]; - } - - updateUIAfterRun() { - super.updateUIAfterRun(); - - if (isInBrowser) { - document.getElementById(this.startupID).innerHTML = uiFriendlyScore(this.startupScore); - document.getElementById(this.runID).innerHTML = uiFriendlyScore(this.runScore); - document.getElementById(this.scoreID).innerHTML = uiFriendlyScore(this.score); - return; - } - - if (dumpJSONResults) - return; - - console.log(" Startup:", uiFriendlyScore(this.startupScore)); - console.log(" Run time:", uiFriendlyScore(this.runScore)); - console.log(" Score:", uiFriendlyScore(this.score)); - if (RAMification) { - console.log(" Current Footprint:", uiFriendlyNumber(this.currentFootprint)); - console.log(" Peak Footprint:", uiFriendlyNumber(this.peakFootprint)); - } - console.log(" Wall time:", uiFriendlyDuration(this.endTime - this.startTime)); - } }; function dotnetPreloads(type) From 781465708e168f0c75c6c1ff4bd3b39820705a86 Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Tue, 29 Jul 2025 15:24:18 +0200 Subject: [PATCH 2/5] cleanup --- JetStreamDriver.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/JetStreamDriver.js b/JetStreamDriver.js index c6e8537c..1df492a3 100644 --- a/JetStreamDriver.js +++ b/JetStreamDriver.js @@ -674,7 +674,7 @@ class Benchmark { allScores() { const allScores = this.subScores(); - allScores["score"] = this.score; + allScores["Score"] = this.score; return allScores; } @@ -1032,8 +1032,12 @@ class Benchmark { return; console.log(this.name); - for (const [name, value] of scoreEntries) + for (let [name, value] of scoreEntries) { + // Rename for backwards compatibility. + if (name == "Worst") + name = "Worst Case" console.log(` ${name}:`, uiFriendlyScore(value)); + } if (RAMification) { console.log(" Current Footprint:", uiFriendlyNumber(this.currentFootprint)); console.log(" Peak Footprint:", uiFriendlyNumber(this.peakFootprint)); From 084d66f79d09ca22896e5aa961a0312d7bc500b4 Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Tue, 29 Jul 2025 16:13:02 +0200 Subject: [PATCH 3/5] add unittest --- tests/unit-tests.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/unit-tests.js b/tests/unit-tests.js index 7260a3f6..f8efd23a 100644 --- a/tests/unit-tests.js +++ b/tests/unit-tests.js @@ -64,3 +64,30 @@ function assertEquals(actual, expected, message) { assertTrue(enabledBenchmarkNames.has(benchmark.name)); } })(); + + +(function testBenchmarkSubScores() { + for (const benchmark of BENCHMARKS) { + const subScores = benchmark.subScores(); + assertTrue(subScores instanceof Object); + assertTrue(Object.keys(subScores).length > 0); + for (const [name, value] of Object.entries(subScores)) { + assertTrue(typeof(name) == "string"); + // "Score" can only be part of allScores(). + assertFalse(name == "Score"); + // Without running all values should be null. + assertEquals(value, null); + } + } +})(); + +(function testBenchmarkAllScores() { + for (const benchmark of BENCHMARKS) { + const subScores = benchmark.subScores(); + const allScores = benchmark.allScores(); + assertTrue("Score" in allScores); + // All subScore items are part of allScores. + for (const name of Object.keys(subScores)) + assertTrue(name in allScores); + } +})(); From 6457ac73c63ae7bce2b6d924d3288e5b879b933c Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Tue, 29 Jul 2025 16:28:24 +0200 Subject: [PATCH 4/5] update --- JetStreamDriver.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/JetStreamDriver.js b/JetStreamDriver.js index 1df492a3..a7bd4f58 100644 --- a/JetStreamDriver.js +++ b/JetStreamDriver.js @@ -674,7 +674,7 @@ class Benchmark { allScores() { const allScores = this.subScores(); - allScores["Score"] = this.score; + allScores["Score"] = this.score; return allScores; } @@ -994,8 +994,8 @@ class Benchmark { return ids; } - scoreIdentifier(name) { - return `results-cell-${this.name}-${name}`; + scoreIdentifier(scoreName) { + return `results-cell-${this.name}-${scoreName}`; } updateUIBeforeRun() { @@ -1032,10 +1032,18 @@ class Benchmark { return; console.log(this.name); + // FIXME: consider removing this mapping. + // Rename for backwards compatibility. + const legacyScoreNameMap = { + __proto__: null, + "First": "Startup", + "Worst": "Worst Case", + "MainRun": "Tests", + "Runtime": "Run time", + }; for (let [name, value] of scoreEntries) { - // Rename for backwards compatibility. - if (name == "Worst") - name = "Worst Case" + if (name in legacyScoreNameMap) + name = legacyScoreNameMap[name]; console.log(` ${name}:`, uiFriendlyScore(value)); } if (RAMification) { From f3e4848ee9a1998db8b73909bf0bab299f316c1a Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Tue, 29 Jul 2025 19:03:17 +0200 Subject: [PATCH 5/5] fix --- JetStreamDriver.js | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/JetStreamDriver.js b/JetStreamDriver.js index a7bd4f58..e556c758 100644 --- a/JetStreamDriver.js +++ b/JetStreamDriver.js @@ -999,12 +999,13 @@ class Benchmark { } updateUIBeforeRun() { - if (!isInBrowser) { - if (!dumpJSONResults) - console.log(`Running ${this.name}:`); - return; - } + if (!dumpJSONResults) + console.log(`Running ${this.name}:`); + if (isInBrowser) + this.updateUIBeforeRunInBrowser(); + } + updateUIBeforeRunInBrowser() { const containerUI = document.getElementById("results"); const resultsBenchmarkUI = document.getElementById(`benchmark-${this.name}`); containerUI.insertBefore(resultsBenchmarkUI, containerUI.firstChild); @@ -1015,23 +1016,24 @@ class Benchmark { } updateUIAfterRun() { - if (!isInBrowser) + const scoreEntries = Object.entries(this.allScores()); + if (isInBrowser) + this.updateUIAfterRunInBrowser(scoreEntries); + if (dumpJSONResults) return; + this.updateConsoleAfterRun(scoreEntries); + } + updateUIAfterRunInBrowser(scoreEntries) { const benchmarkResultsUI = document.getElementById(`benchmark-${this.name}`); benchmarkResultsUI.classList.remove("benchmark-running"); benchmarkResultsUI.classList.add("benchmark-done"); - const scoreEntries = Object.entries(this.allScores()); - if (isInBrowser) { - for (const [name, value] of scoreEntries) - document.getElementById(this.scoreIdentifier(name)).innerHTML = uiFriendlyScore(value); - } - - if (dumpJSONResults) - return; + for (const [name, value] of scoreEntries) + document.getElementById(this.scoreIdentifier(name)).innerHTML = uiFriendlyScore(value); + } - console.log(this.name); + updateConsoleAfterRun(scoreEntries) { // FIXME: consider removing this mapping. // Rename for backwards compatibility. const legacyScoreNameMap = {