Skip to content

Instantly share code, notes, and snippets.

@noseratio
Last active July 6, 2021 02:21
Show Gist options
  • Save noseratio/aeabb3fb4afecd4e4e17875b0da8aa45 to your computer and use it in GitHub Desktop.
Save noseratio/aeabb3fb4afecd4e4e17875b0da8aa45 to your computer and use it in GitHub Desktop.
Timing various Deferred implementations
void async function() {
// DeferredAsClass
class DeferredAsClass {
resolve;
reject;
promise = new Promise((s, f) => { this.resolve = s; this.reject = f; });
}
// DeferredAsClassWithConstructor
class DeferredAsClassWithConstructor {
resolve;
reject;
promise;
constructor() {
this.promise = new Promise((s, f) => { this.resolve = s; this.reject = f; });
}
}
// DeferredAsDerivedClass
class DeferredAsDerivedClass extends Promise {
resolve;
reject;
static get [Symbol.species]() {
return Promise;
}
constructor() {
let resolve, reject;
super((s, f) => { resolve = s; reject = f; });
this.resolve = resolve; this.reject = reject;
}
}
// DeferredAsFunc
function DeferredAsFunc() {
this.promise = new Promise((s, f) => { this.resolve = s; this.reject = f; });
}
// createDeferredAsObject
function createDeferredAsObject() {
const d = {}
d.promise = new Promise((s, f) => { d.resolve = s; d.reject = f; });
return d;
}
// make sure each deferred works as expected
async function testDeferred(tag, creator, ms) {
const start = Date.now();
console.time(tag);
const d = creator();
setTimeout(() => d.resolve(), ms);
await (d.then ? d: d.promise);
console.timeEnd(tag);
console.assert(Date.now() - start >= ms);
}
const delayMs = 500;
await testDeferred("DeferredAsClass", () => new DeferredAsClass(), delayMs)
await testDeferred("DeferredAsClassWithConstructor", () => new DeferredAsClassWithConstructor(), delayMs)
await testDeferred("DeferredAsDerivedClass", () => new DeferredAsDerivedClass(), delayMs)
await testDeferred("DeferredAsFunc", () => new DeferredAsFunc(), delayMs)
await testDeferred("createDeferredAsObject", createDeferredAsObject, delayMs)
// timing
console.log("*** timing ***")
// this test can be slow in Firefox
const iterations = /firefox/i.test(globalThis.navigator?.userAgent) ?
100_000: ((globalThis.Deno || globalThis.process) ? 3_000_000: 1_000_000);
const cached = Promise.resolve();
async function timeMany(tag, creator) {
console.time(tag);
for (let n = 0; n < iterations; n++) {
await creator(s => queueMicrotask(s));
}
console.timeEnd(tag);
}
// timing new Promise directly
await timeMany("Promise", executor => new Promise(executor));
// timing new DeferredAsClass()
await timeMany("DeferredAsClass", executor => {
const d = new DeferredAsClass();
executor(d.resolve, d.reject);
return d.promise;
});
// timing new DeferredAsClassWithConstructor()
await timeMany("DeferredAsClassWithConstructor", executor => {
const d = new DeferredAsClassWithConstructor();
executor(d.resolve, d.reject);
return d.promise;
});
// timing new DeferredAsDerivedClass()
await timeMany("DeferredAsDerivedClass", executor => {
const d = new DeferredAsDerivedClass();
executor(d.resolve, d.reject);
return d;
});
// timing new DeferredAsFunc()
await timeMany("DeferredAsFunc", executor => {
const d = new DeferredAsFunc();
executor(d.resolve, d.reject);
return d.promise;
});
// timing createDeferredAsObject
await timeMany("createDeferredAsObject", executor => {
const d = createDeferredAsObject();
executor(d.resolve, d.reject);
return d.promise;
});
}().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment