Skip to content

Commit

Permalink
Use an efficient queue implementation (#15)
Browse files Browse the repository at this point in the history
* Consistent use of semicolons.

* Add a basic perf test.

* Use a Deque.
  • Loading branch information
cpojer authored and ForbesLindesay committed Jun 4, 2017
1 parent 749707f commit 600dc43
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
34 changes: 18 additions & 16 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
'use strict'

var Deque = require('double-ended-queue');

module.exports = function (PromiseArgument) {
var Promise;
function throat(size, fn) {
var queue = []
var queue = new Deque();
function run(fn, self, args) {
if (size) {
size--
size--;
var result = new Promise(function (resolve) {
resolve(fn.apply(self, args))
})
result.then(release, release)
return result
resolve(fn.apply(self, args));
});
result.then(release, release);
return result;
} else {
return new Promise(function (resolve) {
queue.push(new Delayed(resolve, fn, self, args))
})
queue.push(new Delayed(resolve, fn, self, args));
});
}
}
function release() {
size++
if (queue.length) {
var next = queue.shift()
next.resolve(run(next.fn, next.self, next.args))
size++;
if (!queue.isEmpty()) {
var next = queue.shift();
next.resolve(run(next.fn, next.self, next.args));
}
}
if (typeof size === 'function') {
Expand Down Expand Up @@ -83,8 +85,8 @@ if (typeof Promise === 'function') {
}

function Delayed(resolve, fn, self, args) {
this.resolve = resolve
this.fn = fn
this.self = self || null
this.args = args
this.resolve = resolve;
this.fn = fn;
this.self = self || null;
this.args = args;
}
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"parallelism",
"limit"
],
"dependencies": {},
"dependencies": {
"double-ended-queue": "^2.1.0-0"
},
"devDependencies": {
"coveralls": "^2.11.2",
"istanbul": "^0.4.5",
Expand All @@ -31,4 +33,4 @@
},
"author": "ForbesLindesay",
"license": "MIT"
}
}
15 changes: 15 additions & 0 deletions perf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const throat = require('./index');

const promises = [];
for (let i = 0; i < 1000000; i++) {
promises.push(() => new Promise(resolve => process.nextTick(resolve)));
}

Promise.resolve().then(async () => {
for (let amount = 10; amount <= 1000000; amount = amount * 10) {
const list = promises.slice(0, amount);
console.time(amount + ' promises');
await Promise.all(list.map(throat(10, fn => fn())));
console.timeEnd(amount + ' promises');
}
});

0 comments on commit 600dc43

Please sign in to comment.