Skip to content

Instantly share code, notes, and snippets.

@justinvdm
Last active January 7, 2018 20:01
Show Gist options
  • Save justinvdm/f6f04c5872075afb3dde5bd3504f2d0c to your computer and use it in GitHub Desktop.
Save justinvdm/f6f04c5872075afb3dde5bd3504f2d0c to your computer and use it in GitHub Desktop.
const assert = require('assert');
const flowSync = fns => v0 => {
let i = -1;
let v = v0;
const n = fns.length;
while (++i < n) v = fns[i](v);
return v;
};
const flowAsync = fns => v0 => {
let i = -1;
let p = Promise.resolve(v0);
const n = fns.length;
while (++i < n) p = p.then(fns[i]);
return p;
};
const flowAsyncNextCb = fns => v0 => {
let i = -1;
const n = fns.length;
let resolve;
let reject;
const p = new Promise((_resolve, _reject) => {
resolve = _resolve
reject = _reject;
});
const next = v => {
if (++i === n) {
resolve(v);
return;
}
Promise.resolve(v)
.then(fns[i])
.then(next, reject);
};
next(v0);
return p;
};
const flowAsyncNextCbDuckType = fns => v0 => {
let i = -1;
const n = fns.length;
let resolve;
let reject;
const p = new Promise((_resolve, _reject) => {
resolve = _resolve
reject = _reject;
});
const next = v => {
if (++i === n) {
resolve(v);
return;
}
if (v && v.then) {
v.then(fns[i]).then(next, reject);
return;
}
let res;
try {
res = fns[i](v);
} catch (e) {
reject(e);
return;
}
next(res);
};
next(v0);
return p;
};
const fnsSync = [
v => v + 1, v => v + 2, v => v + 3, v => v + 4, v => v + 5, v => v + 6,
v => v + 7, v => v + 8, v => v + 9, v => v + 10, v => v + 11, v => v + 13,
v => v + 14, v => v + 15, v => v + 16, v => v + 17, v => v + 18, v => v + 19,
v => v + 20, v => v + 21, v => v + 22, v => v + 23
];
const fnsAsync = [
v => v + 1, v => v + 2, v => v + 3, v => v + 4, v => v + 5, v => v + 6, v =>
v + 7, v => v + 8, v => v + 9, v => Promise.resolve(v + 10), v => v + 11,
v => v + 13, v => v + 14, v => v + 15, v => v + 16,
v => Promise.resolve(v + 17), v => v + 18, v => v + 19, v => v + 20,
v => v + 21, v => v + 22, v => v + 23
];
const fnSync = flowSync(fnsSync);
const fnAsync = flowAsync(fnsAsync);
const fnAsyncNextCb = flowAsyncNextCb(fnsAsync);
const fnAsyncNextCbDuckType = flowAsyncNextCbDuckType(fnsAsync);
const fnAsyncNextCbDuckTypeSync = flowAsyncNextCbDuckType(fnsSync);
const test = done => {
assert.equal(264, fnSync(0));
Promise.all([
fnAsync(0),
fnAsyncNextCb(0),
fnAsyncNextCbDuckType(0),
fnAsyncNextCbDuckTypeSync(0)
]).then(res => {
assert.deepEqual([264, 264, 264, 264], res);
done();
});
};
suite('promise-resolve-wrap', () => {
const {N = 1000} = require('./conf');
before(done => {
test(done);
});
bench('no promises', () => {
let i = -1;
while (++i < N) fnSync(i);
});
bench('promise wrapped', done => {
let i = -1;
const next = () => {
if (++i === N) return done();
fnAsync(i).then(next);
};
next();
});
bench('promise wrapped (next cb)', done => {
let i = -1;
const next = () => {
if (++i === N) return done();
fnAsyncNextCb(i).then(next);
};
next();
});
bench('promise wrapped (next cb, duck typed)', done => {
let i = -1;
const next = () => {
if (++i === N) return done();
fnAsyncNextCbDuckType(i).then(next);
};
next();
});
bench('promise wrapped (next cb, duck typed, sync fns)', done => {
let i = -1;
const next = () => {
if (++i === N) return done();
fnAsyncNextCbDuckTypeSync(i).then(next);
};
next();
});
});
promise-resolve-wrap
no promises .................................... 4,181 op/s
promise wrapped ................................ 138 op/s
promise wrapped (next cb) ...................... 70 op/s
promise wrapped (next cb, duck typed) .......... 363 op/s
promise wrapped (next cb, duck typed, sync fns) 670 op/s
Suites: 1
Benches: 5
Elapsed: 5,090.72 ms
let N;
if (process.env.BENCH_N) N = process.env.BENCH_N;
if (process.env.TEST) {
set('type', 'static');
set('iterations', 1);
N = 1;
}
module.exports = {
N
};
{
"name": "bench-promise-wrap",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"drip": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/drip/-/drip-1.1.0.tgz",
"integrity": "sha1-zO+x5obYb8EVtwyewSb4+HG9/X4=",
"dev": true,
"requires": {
"tea-concat": "0.1.0"
}
},
"electron": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-0.4.1.tgz",
"integrity": "sha1-p4oFGniC9OVC1uIH2KGnMHazAUQ=",
"dev": true,
"requires": {
"drip": "1.1.0"
}
},
"matcha": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/matcha/-/matcha-0.7.0.tgz",
"integrity": "sha1-E/gFQJs3vlcDLIRYZDvxUjumjdo=",
"dev": true,
"requires": {
"electron": "0.4.1",
"v8-argv": "0.1.0"
}
},
"tea-concat": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/tea-concat/-/tea-concat-0.1.0.tgz",
"integrity": "sha1-6i6QdAD914pjNM4CD6PGlQLZnoQ=",
"dev": true
},
"v8-argv": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/v8-argv/-/v8-argv-0.1.0.tgz",
"integrity": "sha1-rfd3pS29w9qciclGXlntXzy22ak=",
"dev": true
}
}
}
{
"name": "bench-promise-wrap",
"version": "1.0.0",
"description": "",
"main": "++bench-promise-wrap.js",
"scripts": {
"test": "TEST=1 npm run bench",
"start": "npm run bench --silent | tee +results.txt",
"bench": "matcha -R plain *.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"matcha": "^0.7.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment