Skip to content

Commit

Permalink
Replacing the built-in array with Infiniqueue. Performance penalty fo…
Browse files Browse the repository at this point in the history
…r small queues but huge boost for big queues. May be able to improve the perf penalty later.
  • Loading branch information
David Ellis committed Oct 5, 2013
1 parent 84eb67f commit 7fcf830
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 11 deletions.
37 changes: 29 additions & 8 deletions lib/queue-flow.js
Expand Up @@ -21,6 +21,7 @@
var isAsync = require('is-async');
var EventEmitter = require('async-cancelable-events');
var util = require('util');
var Infiniqueue = require('infiniqueue');

var nextTick = global.setImmediate ? global.setImmediate : process.nextTick;

Expand Down Expand Up @@ -110,7 +111,12 @@ function Q(nameOrArray, namespace) {

// Private variables, the handlers and actual queue array
this.wasName = nameOrArray instanceof Array ? false : true;
var queue = this.queue = nameOrArray instanceof Array ? nameOrArray : [];
var queue = new Infiniqueue();
if(nameOrArray instanceof Array) {
for(var i = 0; i < nameOrArray.length; i++) {
queue.enqueue(nameOrArray[i]);
}
}
var handler = function() {};
var handlerSet = false;
var handlerBusy = false;
Expand All @@ -132,7 +138,7 @@ function Q(nameOrArray, namespace) {
var handlerEmitter = this.emit.bind(this);
var handlerRuns = 0;
function handlerCall() {
handler(queue.shift(), handlerCallback);
handler(queue.dequeue(), handlerCallback);
}

// The `handlerCallback` is provided to the handler along with the dequeued value.
Expand Down Expand Up @@ -164,7 +170,9 @@ function Q(nameOrArray, namespace) {
recentlyEmptied = false;
var values = Array.prototype.slice.call(arguments, 0);
this.emitSync('push', values);
Array.prototype.push.apply(queue, values);
for(var i = 0; i < values.length; i++) {
queue.enqueue(values[i]);
}
if(handlerSet && !handlerBusy) handlerCallback(function() {});
return this;
}.bind(this);
Expand All @@ -179,7 +187,7 @@ function Q(nameOrArray, namespace) {
this.pushOne = function pushOne(val) {
recentlyEmptied = false;
this.emitSync('push', [val]);
queue.push(val);
queue.enqueue(val);
if(handlerSet && !handlerBusy) handlerCallback(function() {});
return this;
}.bind(this);
Expand All @@ -198,6 +206,7 @@ function Q(nameOrArray, namespace) {
var tempHandler = handler;
handlerSet = false;
handler = function() {};
queue.shutdown();
queue = undefined;
this.push = this.pushOne = function() { throw new Error('Queue already closed'); };
if(namespace) namespace.clearQueue(this);
Expand All @@ -224,6 +233,7 @@ function Q(nameOrArray, namespace) {
var tempHandler = handler;
handlerSet = false;
handler = function() {};
queue.shutdown();
queue = undefined;
this.push = this.pushOne = function() { throw new Error('Queue already closed'); };
if(namespace) namespace.clearQueue(this);
Expand Down Expand Up @@ -524,14 +534,25 @@ Q.prototype.someSync = makeSync(Q.prototype.some);
// falsy.
Q.prototype.toArray = function toArray(last) {
var outQueue = this;
var outArr = [];
if(!last) {
outQueue = new this.constructor(null, this.namespace);
this.on('close', function() { outQueue.push(this.queue).close(); }.bind(this));
} else if(typeof last === 'string') {
this.on('close', function() { q(last).push(this.queue).close(); }.bind(this));
} else if(typeof last === 'function') {
this.on('close', last.bind(this, this.queue));
outQueue = q(last);
}
this.setHandler(function(value, next) {
if(next) {
next(function() {
outArr.push(value);
});
} else {
if(typeof last === 'function') {
last(outArr);
} else {
outQueue.push(outArr)[value]();
}
}
});
if(!this.wasName) this.close();
return outQueue;
};
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -13,7 +13,8 @@
"main": "./lib/queue-flow",
"dependencies": {
"is-async": "0.0.2",
"async-cancelable-events": "0.0.6"
"async-cancelable-events": "0.0.6",
"infiniqueue": "0.1.2"
},
"devDependencies": {
"nodeunit": "*",
Expand Down
2 changes: 1 addition & 1 deletion test/test-perf.js
Expand Up @@ -9,7 +9,7 @@ exports.perf = function(test) {
bootstrap(test);
test.expect(2);
var testArray = [];
var runs = 100000;
var runs = 3000000;
for(var i = 0; i < runs; i++) {
testArray[i] = i;
}
Expand Down
2 changes: 1 addition & 1 deletion test/test.js
Expand Up @@ -48,7 +48,7 @@ exports.as = function(test) {
bootstrap(test);
test.expect(1);
q([1, 2, 3]).as('test1');
q('test1').close().toArray(function(result) {
q('test1').toArray(function(result) {
test.equal([1, 2, 3].toString(), result.toString(), 'named queue properly referenceable');
test.done();
});
Expand Down

0 comments on commit 7fcf830

Please sign in to comment.