Skip to content

Commit a999ad1

Browse files
authored
Don't display invalid results (#406)
This partially fixes #399 by not display non-finite scores which are caused by 0-measured suite results. - For non-positive or non-finite scores, the following summary page is displayed. Note that the detailed page is still accessible since you might find some useful information there. - Additionally, a console.error is generated for each zero-sum suite
1 parent e6e8a4f commit a999ad1

File tree

4 files changed

+97
-23
lines changed

4 files changed

+97
-23
lines changed

index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
</div>
5151
</section>
5252

53-
<section id="summary" data-title="Results Summary">
53+
<section id="summary" data-title="Results Summary" class="valid">
5454
<a href="#home" class="logo">
5555
<img srcset="resources/[email protected] 2x" src="resources/logo.png" alt="Speedometer" />
5656
<div class="version">3.0</div>
@@ -62,6 +62,10 @@ <h1>Score</h1>
6262
<hr />
6363
<div id="result-number"></div>
6464
<div id="confidence-number"></div>
65+
<div id="invalid-score-text">
66+
One or more subtests produced no duration.<br />
67+
Please check your <a href="./instructions.html" target="_blank">browser settings</a> and re-run the benchmark.<br />
68+
</div>
6569
<div class="buttons">
6670
<div class="button-row">
6771
<a class="button" href="#details" id="show-details" title="Show detailed results data.">Details</a>

resources/benchmark-runner.mjs

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -339,17 +339,29 @@ export class BenchmarkRunner {
339339
if (this._client?.willStartFirstIteration)
340340
await this._client.willStartFirstIteration(iterationCount);
341341

342+
try {
343+
await this._runMultipleIterations();
344+
} catch (error) {
345+
console.error(error);
346+
if (this._client?.handleError) {
347+
await this._client.handleError(error);
348+
return;
349+
}
350+
}
351+
352+
if (this._client?.didFinishLastIteration)
353+
await this._client.didFinishLastIteration(this._metrics);
354+
}
355+
356+
async _runMultipleIterations() {
342357
const iterationStartLabel = "iteration-start";
343358
const iterationEndLabel = "iteration-end";
344-
for (let i = 0; i < iterationCount; i++) {
359+
for (let i = 0; i < this._iterationCount; i++) {
345360
performance.mark(iterationStartLabel);
346361
await this._runAllSuites();
347362
performance.mark(iterationEndLabel);
348363
performance.measure(`iteration-${i}`, iterationStartLabel, iterationEndLabel);
349364
}
350-
351-
if (this._client?.didFinishLastIteration)
352-
await this._client.didFinishLastIteration(this._metrics);
353365
}
354366

355367
_removeFrame() {
@@ -402,15 +414,21 @@ export class BenchmarkRunner {
402414
suites[j] = tmp;
403415
}
404416
}
405-
406417
performance.mark(prepareEndLabel);
407418
performance.measure("runner-prepare", prepareStartLabel, prepareEndLabel);
408419

409-
for (const suite of suites) {
410-
if (!suite.disabled)
411-
await this._runSuite(suite);
420+
try {
421+
for (const suite of suites) {
422+
if (!suite.disabled)
423+
await this._runSuite(suite);
424+
}
425+
426+
} finally {
427+
await this._finishRunAllSuites();
412428
}
429+
}
413430

431+
async _finishRunAllSuites() {
414432
const finalizeStartLabel = "runner-finalize-start";
415433
const finalizeEndLabel = "runner-finalize-end";
416434

@@ -423,10 +441,11 @@ export class BenchmarkRunner {
423441
}
424442

425443
async _runSuite(suite) {
426-
const suitePrepareStartLabel = `suite-${suite.name}-prepare-start`;
427-
const suitePrepareEndLabel = `suite-${suite.name}-prepare-end`;
428-
const suiteStartLabel = `suite-${suite.name}-start`;
429-
const suiteEndLabel = `suite-${suite.name}-end`;
444+
const suiteName = suite.name;
445+
const suitePrepareStartLabel = `suite-${suiteName}-prepare-start`;
446+
const suitePrepareEndLabel = `suite-${suiteName}-prepare-end`;
447+
const suiteStartLabel = `suite-${suiteName}-start`;
448+
const suiteEndLabel = `suite-${suiteName}-end`;
430449

431450
performance.mark(suitePrepareStartLabel);
432451
await this._prepareSuite(suite);
@@ -437,8 +456,18 @@ export class BenchmarkRunner {
437456
await this._runTestAndRecordResults(suite, test);
438457
performance.mark(suiteEndLabel);
439458

440-
performance.measure(`suite-${suite.name}-prepare`, suitePrepareStartLabel, suitePrepareEndLabel);
441-
performance.measure(`suite-${suite.name}`, suiteStartLabel, suiteEndLabel);
459+
performance.measure(`suite-${suiteName}-prepare`, suitePrepareStartLabel, suitePrepareEndLabel);
460+
performance.measure(`suite-${suiteName}`, suiteStartLabel, suiteEndLabel);
461+
this._validateSuiteTotal(suiteName);
462+
}
463+
464+
_validateSuiteTotal(suiteName) {
465+
// When the test is fast and the precision is low (for example with Firefox'
466+
// privacy.resistFingerprinting preference), it's possible that the measured
467+
// total duration for an entire is 0.
468+
const suiteTotal = this._measuredValues.tests[suiteName].total;
469+
if (suiteTotal === 0)
470+
throw new Error(`Got invalid 0-time total for suite ${suiteName}: ${suiteTotal}`);
442471
}
443472

444473
async _prepareSuite(suite) {

resources/main.css

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,25 @@ section#summary > #confidence-number {
423423
color: var(--inactive-color);
424424
}
425425

426+
section#summary.invalid h1,
427+
section#summary.invalid .gauge,
428+
section#summary.invalid hr {
429+
opacity: 0.2;
430+
}
431+
section#summary.invalid #result-number {
432+
color: var(--highlight);
433+
}
434+
section#summary.invalid .buttons {
435+
display: none;
436+
}
437+
#invalid-score-text {
438+
display: none;
439+
text-align: center;
440+
}
441+
section#summary.invalid #invalid-score-text {
442+
display: block;
443+
}
444+
426445
section#details {
427446
--viewport-height: max(600px, 90vh);
428447
--viewport-width: max(800px, 80vw);

resources/main.mjs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,42 @@ class MainBenchmarkClient {
107107
this._metrics = metrics;
108108

109109
const scoreResults = this._computeResults(this._measuredValuesList, "score");
110-
this._updateGaugeNeedle(scoreResults.mean);
111-
document.getElementById("result-number").textContent = scoreResults.formattedMean;
112-
if (scoreResults.formattedDelta)
113-
document.getElementById("confidence-number").textContent = `\u00b1 ${scoreResults.formattedDelta}`;
110+
if (scoreResults.isValid)
111+
this._populateValidScore(scoreResults);
112+
else
113+
this._populateInvalidScore();
114114

115115
this._populateDetailedResults(metrics);
116-
117116
if (params.developerMode)
118117
this.showResultsDetails();
119118
else
120119
this.showResultsSummary();
121120
}
122121

122+
handleError(error) {
123+
console.assert(this._isRunning);
124+
this._isRunning = false;
125+
this._hasResults = true;
126+
this._metrics = Object.create(null);
127+
this._populateInvalidScore();
128+
this.showResultsSummary();
129+
}
130+
131+
_populateValidScore(scoreResults) {
132+
document.getElementById("summary").className = "valid";
133+
134+
this._updateGaugeNeedle(scoreResults.mean);
135+
document.getElementById("result-number").textContent = scoreResults.formattedMean;
136+
if (scoreResults.formattedDelta)
137+
document.getElementById("confidence-number").textContent = `\u00b1 ${scoreResults.formattedDelta}`;
138+
}
139+
140+
_populateInvalidScore() {
141+
document.getElementById("summary").className = "invalid";
142+
document.getElementById("result-number").textContent = "Error";
143+
document.getElementById("confidence-number").textContent = "";
144+
}
145+
123146
_computeResults(measuredValuesList, displayUnit) {
124147
function valueForUnit(measuredValues) {
125148
if (displayUnit === "ms")
@@ -137,9 +160,7 @@ class MainBenchmarkClient {
137160
}
138161

139162
const values = measuredValuesList.map(valueForUnit);
140-
const sum = values.reduce((a, b) => {
141-
return a + b;
142-
}, 0);
163+
const sum = values.reduce((a, b) => a + b, 0);
143164
const arithmeticMean = sum / values.length;
144165
let meanSigFig = 4;
145166
let formattedDelta;
@@ -162,6 +183,7 @@ class MainBenchmarkClient {
162183
formattedMean: formattedMean,
163184
formattedDelta: formattedDelta,
164185
formattedMeanAndDelta: formattedMean + (formattedDelta ? ` \xb1 ${formattedDelta} (${formattedPercentDelta})` : ""),
186+
isValid: values.length > 0 && isFinite(sum) && sum > 0,
165187
};
166188
}
167189

0 commit comments

Comments
 (0)