Skip to content

Commit faf9fff

Browse files
authored
Avoid measurement dead-spot between sync and async phase (#464)
We could potentially miss a gc between the performance.mark calls for syncEndTime and asyncStartTime. This PR changes the code to reuse the sync end times and marker for the async start.
1 parent a169b1d commit faf9fff

File tree

2 files changed

+14
-25
lines changed

2 files changed

+14
-25
lines changed

resources/shared/test-runner.mjs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export class TestRunner {
2424
const testName = this.#test.name;
2525
const syncStartLabel = `${suiteName}.${testName}-start`;
2626
const syncEndLabel = `${suiteName}.${testName}-sync-end`;
27-
const asyncStartLabel = `${suiteName}.${testName}-async-start`;
2827
const asyncEndLabel = `${suiteName}.${testName}-async-end`;
2928

3029
let syncTime;
@@ -43,13 +42,11 @@ export class TestRunner {
4342
performance.mark(syncStartLabel);
4443
const syncStartTime = performance.now();
4544
this.#test.run(this.#page);
46-
const syncEndTime = performance.now();
47-
performance.mark(syncEndLabel);
45+
const mark = performance.mark(syncEndLabel);
46+
const syncEndTime = mark.startTime;
4847

4948
syncTime = syncEndTime - syncStartTime;
50-
51-
performance.mark(asyncStartLabel);
52-
asyncStartTime = performance.now();
49+
asyncStartTime = syncEndTime;
5350
};
5451
const measureAsync = () => {
5552
const bodyReference = this.#frame ? this.#frame.contentDocument.body : document.body;
@@ -67,7 +64,7 @@ export class TestRunner {
6764
if (this.#params.warmupBeforeSync)
6865
performance.measure("warmup", "warmup-start", "warmup-end");
6966
performance.measure(`${suiteName}.${testName}-sync`, syncStartLabel, syncEndLabel);
70-
performance.measure(`${suiteName}.${testName}-async`, asyncStartLabel, asyncEndLabel);
67+
performance.measure(`${suiteName}.${testName}-async`, syncEndLabel, asyncEndLabel);
7168
};
7269

7370
const report = () => this.#callback(this.#test, syncTime, asyncTime);

tests/benchmark-runner-tests.mjs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,6 @@ const CLIENT_FIXTURE = {
2929
didRunSuites: sinon.stub(),
3030
};
3131

32-
function stubPerformanceNowCalls(syncStart, syncEnd, asyncStart, asyncEnd) {
33-
sinon
34-
.stub(window.performance, "now")
35-
.onFirstCall()
36-
.returns(syncStart) // startTime (sync)
37-
.onSecondCall()
38-
.returns(syncEnd) // endTime (sync)
39-
.onThirdCall()
40-
.returns(asyncStart) // startTime (async)
41-
.returns(asyncEnd); // endTime (async)
42-
}
43-
4432
describe("BenchmarkRunner", () => {
4533
const { spy, stub, assert } = sinon;
4634
let runner;
@@ -206,13 +194,12 @@ describe("BenchmarkRunner", () => {
206194
it("should write performance marks at the start and end of the test with the correct test name", () => {
207195
assert.calledWith(performanceMarkSpy, "Suite 1.Test 1-start");
208196
assert.calledWith(performanceMarkSpy, "Suite 1.Test 1-sync-end");
209-
assert.calledWith(performanceMarkSpy, "Suite 1.Test 1-async-start");
210197
assert.calledWith(performanceMarkSpy, "Suite 1.Test 1-async-end");
211198

212199
// SuiteRunner adds 2 marks.
213200
// Suite used here contains 3 tests.
214-
// Each Testrunner adds 4 marks.
215-
expect(performanceMarkSpy.callCount).to.equal(14);
201+
// Each TestRunner adds 3 marks.
202+
expect(performanceMarkSpy.callCount).to.equal(11);
216203
});
217204
});
218205

@@ -222,7 +209,6 @@ describe("BenchmarkRunner", () => {
222209

223210
const syncStart = 8000;
224211
const syncEnd = 10000;
225-
const asyncStart = 12000;
226212
const asyncEnd = 13000;
227213

228214
const params = { measurementMethod: "raf" };
@@ -232,7 +218,13 @@ describe("BenchmarkRunner", () => {
232218
tests: {},
233219
});
234220

235-
stubPerformanceNowCalls(syncStart, syncEnd, asyncStart, asyncEnd);
221+
const originalMark = window.performance.mark.bind(window.performance);
222+
const performanceMarkStub = sinon.stub(window.performance, "mark").withArgs(sinon.match.any).callThrough();
223+
const performanceNowStub = sinon.stub(window.performance, "now");
224+
225+
performanceNowStub.onFirstCall().returns(syncStart);
226+
performanceMarkStub.onThirdCall().callsFake((markName) => originalMark(markName, { startTime: asyncEnd }));
227+
performanceNowStub.onSecondCall().returns(asyncEnd);
236228

237229
// instantiate recorded test results
238230
const suiteRunner = new SuiteRunner(runner._frame, runner._page, params, suite, runner._client, runner._measuredValues);
@@ -243,7 +235,7 @@ describe("BenchmarkRunner", () => {
243235

244236
it("should calculate measured test values correctly", () => {
245237
const syncTime = syncEnd - syncStart;
246-
const asyncTime = asyncEnd - asyncStart;
238+
const asyncTime = asyncEnd - syncEnd;
247239

248240
const total = syncTime + asyncTime;
249241
const mean = total / suite.tests.length;

0 commit comments

Comments
 (0)