Skip to content

Instantly share code, notes, and snippets.

@orihomie
Last active May 21, 2022 03:28
Show Gist options
  • Save orihomie/a4e016d6919b39ee203b32bf7cbf3b2a to your computer and use it in GitHub Desktop.
Save orihomie/a4e016d6919b39ee203b32bf7cbf3b2a to your computer and use it in GitHub Desktop.
Comparing bluebird to a custom promise processing
const Bluebird = require('bluebird')
async function delay(ms) {
await new Promise(resolve => setTimeout(resolve, ms))
}
async function saveToDB(fromWhere, value) {
const saveStartedAt = Date.now()
if (value % 5 === 0) {
await delay(2000)
} else {
await delay(100)
}
const saveFinishedAt = Date.now()
if (ITER_LOG) {
console.log(value, 'saved to DB', fromWhere, 'started', saveStartedAt, 'finished', saveFinishedAt, 'duration:', saveFinishedAt - saveStartedAt)
}
return value
}
const bluebirdMapper = async (method, methodArgs, workers) => {
return await Bluebird.map(
methodArgs,
async elem => method(elem),
{ concurrency: workers }
);
};
const simpleMapper = async (method, methodArgs, workers) => {
let promiseArray = [];
const result = [];
for (let i = 0; i < methodArgs.length; i++) {
promiseArray.push(method(methodArgs[i]));
if (i % workers === 0) {
result.push(...(await Promise.all(promiseArray)));
promiseArray = [];
}
}
if (promiseArray.length > 0) {
result.push(...(await Promise.all(promiseArray)));
promiseArray = [];
}
return result;
};
const recursiveMapper = async (method, methodArgs, workers) => {
const queue = [...methodArgs];
const result = [];
const runner = (resolve) => {
if (! queue.length) {
resolve(null);
return;
}
const arg = queue.pop();
(async () => {
result.push(await method(arg));
runner(resolve);
})()
}
const tasks = Array(workers).fill(0).map(() => {
return new Promise(runner)
})
await Promise.all(tasks)
return result;
};
const loopBackMapper = async (method, methodArgs, workers) => {
const queue = [...methodArgs];
const result = [];
const runner = async () => {
while (queue.length > 0) {
const arg = queue.pop();
result.push(await method(arg));
}
}
const tasks = Array(workers).fill(0).map(() => runner());
await Promise.all(tasks)
return result;
};
const loopAheadMapper = async (method, methodArgs, workers) => {
const queue = [...methodArgs]
const result = []
async function runner() {
while (queue.length > 0) {
const arg = queue.shift()
result.push(await method(arg))
}
}
const tasks = new Array(workers).fill(0).map(() => runner())
await Promise.all(tasks)
return result
}
async function bench(benchMethod, methodArgs, title) {
console.time(title)
const results = await benchMethod(async elem => {
return saveToDB(`from ${title}`, elem)
}, methodArgs, WORKERS_COUNT)
console.timeEnd(title)
}
const ARRAY_SIZE = 50
const WORKERS_COUNT = 5
const ITER_LOG = true
const array = new Array(ARRAY_SIZE).fill(0).map((zero, index) => index + 1)
async function main() {
console.log(array)
await bench(bluebirdMapper, array,'bluebird')
await bench(simpleMapper, array,'simpleMapper')
await bench(recursiveMapper, array,'recursiveMapper')
await bench(loopBackMapper, array,'loopBackMapper')
await bench(loopAheadMapper, array, 'loopAheadMapper');
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment