diff --git a/changelog.md b/changelog.md index deef540ea0..03b2ab796e 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,7 @@ Features - Added disable_resubscribing option to prevent a client from resubscribing after reconnecting (@BridgeAR) - Added rename_commands options to handle renamed commands from the redis config (@digmxl & @BridgeAR) +- Increase performance by exchanging built in queue with [Petka Antonov's](@petkaantonov) [double-ended queue](https://github.com/petkaantonov/deque) and prevent polymorphism (@BridgeAR) Bugfixes diff --git a/index.js b/index.js index c1477dc06a..3188cd42ad 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ var net = require('net'); var URL = require('url'); var util = require('util'); var utils = require('./lib/utils'); -var Queue = require('./lib/queue'); +var Queue = require('double-ended-queue'); var Command = require('./lib/command'); var events = require('events'); var parsers = []; @@ -511,7 +511,7 @@ RedisClient.prototype.connection_gone = function (why) { this.retry_delay = this.connect_timeout - this.retry_totaltime; } - debug("Retry connection in " + this.retry_delay + " ms"); + debug('Retry connection in ' + this.retry_delay + ' ms'); this.retry_timer = setTimeout(retry_connection, this.retry_delay, this); }; diff --git a/lib/queue.js b/lib/queue.js deleted file mode 100644 index 5c9c9917e8..0000000000 --- a/lib/queue.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict'; - -// Queue class adapted from Tim Caswell's pattern library -// http://github.com/creationix/pattern/blob/master/lib/pattern/queue.js - -function Queue() { - this.tail = []; - this.head = []; - this.offset = 0; -} - -Queue.prototype.shift = function () { - if (this.offset === this.head.length) { - var tmp = this.head; - tmp.length = 0; - this.head = this.tail; - this.tail = tmp; - this.offset = 0; - if (this.head.length === 0) { - return; - } - } - var item = this.head[this.offset]; - this.head[this.offset] = null; - this.offset++; - return item; -}; - -Queue.prototype.push = function (item) { - return this.tail.push(item); -}; - -Queue.prototype.forEach = function (fn, thisv) { - var array = this.head.slice(this.offset), i, il; - - array.push.apply(array, this.tail); - - if (thisv) { - for (i = 0, il = array.length; i < il; i += 1) { - fn.call(thisv, array[i], i, array); - } - } else { - for (i = 0, il = array.length; i < il; i += 1) { - fn(array[i], i, array); - } - } - - return array; -}; - -Queue.prototype.getLength = function () { - return this.head.length - this.offset + this.tail.length; -}; - -Object.defineProperty(Queue.prototype, 'length', { - get: function () { - return this.getLength(); - } -}); - -module.exports = Queue; diff --git a/lib/utils.js b/lib/utils.js index 6e5cbad356..6f1661f1d3 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -25,11 +25,12 @@ function replyToStrings(reply) { } if (Array.isArray(reply)) { + var res = new Array(reply.length); for (i = 0; i < reply.length; i++) { // Recusivly call the function as slowlog returns deep nested replies - reply[i] = replyToStrings(reply[i]); + res[i] = replyToStrings(reply[i]); } - return reply; + return res; } return reply; diff --git a/package.json b/package.json index 4b87b9ee19..f26d99e748 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,9 @@ "pretest": "optional-dev-dependency hiredis", "posttest": "jshint ." }, + "dependencies": { + "double-ended-queue": "^2.1.0-0" + }, "devDependencies": { "coveralls": "^2.11.2", "jshint": "^2.8.0", diff --git a/test/queue.spec.js b/test/queue.spec.js deleted file mode 100644 index 51a6bd7bb2..0000000000 --- a/test/queue.spec.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -var assert = require("assert"); -var Queue = require('../lib/queue'); - -describe('queue', function () { - var q = new Queue(); - - describe('push', function () { - it('places values on end of queue', function () { - q.push('a'); - q.push(3); - assert.equal(q.length, 2); - }); - }); - - describe('shift', function () { - it('removes values from front of queue', function () { - assert.equal(q.shift(), 'a'); - }); - }); - - describe('forEach', function () { - it('iterates over values in queue', function () { - q.forEach(function (v) { - assert.equal(v, 3); - }); - }); - }); - - describe('forEachWithScope', function () { - it('provides a scope to the iteration function', function () { - q.forEach(function (v) { - assert.equal(this.foo, 'bar'); - assert.equal(v, 3); - }, {foo: 'bar'}); - }); - }); -});