Add requestAnimationFrame-based measurement method. (#173)
This PR adds a new query string parameter requestAnimationFrame, which takes the value of either "timer" or "raf". "timer" is the existing and default measurement method. When it's "raf", we use two consecutive requestAnimationFrame first of which runs the sync step and second of which schedules a 0s timer to signify the end of async step.
This commit is contained in:
parent
34c169c724
commit
a876f0e419
2 changed files with 38 additions and 5 deletions
|
|
@ -173,7 +173,7 @@ const WarmupSuite = {
|
|||
],
|
||||
};
|
||||
|
||||
class TestInvoker {
|
||||
class TimerTestInvoker {
|
||||
constructor(syncCallback, asyncCallback, reportCallback) {
|
||||
this._syncCallback = syncCallback;
|
||||
this._asyncCallback = asyncCallback;
|
||||
|
|
@ -196,6 +196,29 @@ class TestInvoker {
|
|||
}
|
||||
}
|
||||
|
||||
class RAFTestInvoker {
|
||||
constructor(syncCallback, asyncCallback, reportCallback) {
|
||||
this._syncCallback = syncCallback;
|
||||
this._asyncCallback = asyncCallback;
|
||||
this._reportCallback = reportCallback;
|
||||
}
|
||||
|
||||
start() {
|
||||
return new Promise((resolve) => {
|
||||
requestAnimationFrame(() => this._syncCallback());
|
||||
requestAnimationFrame(() => {
|
||||
setTimeout(() => {
|
||||
this._asyncCallback();
|
||||
setTimeout(async () => {
|
||||
await this._reportCallback();
|
||||
resolve();
|
||||
}, 0);
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class BenchmarkRunner {
|
||||
constructor(suites, client) {
|
||||
this._suites = suites;
|
||||
|
|
@ -327,7 +350,8 @@ export class BenchmarkRunner {
|
|||
performance.measure(`${suite.name}.${test.name}-async`, asyncStartLabel, asyncEndLabel);
|
||||
}
|
||||
const report = () => this._recordTestResults(suite, test, syncTime, asyncTime);
|
||||
const invoker = new TestInvoker(runSync, measureAsync, report);
|
||||
const invokerClass = params.measurementMethod === 'raf' ? RAFTestInvoker : TimerTestInvoker;
|
||||
const invoker = new invokerClass(runSync, measureAsync, report);
|
||||
|
||||
return invoker.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ class Params {
|
|||
iterationCount = 10;
|
||||
suites = [];
|
||||
useWarmupSuite = false;
|
||||
measurementMethod = 'timer';
|
||||
|
||||
constructor(searchParams = undefined) {
|
||||
if (searchParams)
|
||||
|
|
@ -46,14 +47,22 @@ class Params {
|
|||
}
|
||||
this.developerMode = searchParams.has("developerMode");
|
||||
searchParams.delete("developerMode");
|
||||
const unused = Array.from(searchParams.keys());
|
||||
if (unused.length > 0)
|
||||
console.error("Got unused search params", unused);
|
||||
|
||||
if (searchParams.has("useWarmupSuite")) {
|
||||
this.useWarmupSuite = true;
|
||||
searchParams.delete("useWarmupSuite");
|
||||
}
|
||||
|
||||
if (searchParams.has("measurementMethod")) {
|
||||
this.measurementMethod = searchParams.get("measurementMethod");
|
||||
if (this.measurementMethod !== 'timer' && this.measurementMethod !== 'raf')
|
||||
throw new Error(`Invalid measurement method: ${this.measurementMethod}`);
|
||||
searchParams.delete("measurementMethod");
|
||||
}
|
||||
|
||||
const unused = Array.from(searchParams.keys());
|
||||
if (unused.length > 0)
|
||||
console.error("Got unused search params", unused);
|
||||
}
|
||||
|
||||
toSearchParams() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue