diff --git a/lib/sender.js b/lib/sender.js index 1668cb1..83b53b3 100644 --- a/lib/sender.js +++ b/lib/sender.js @@ -8,6 +8,7 @@ const tls = require('tls'); const zlib = require('zlib'); const FluentLoggerError = require('./logger-error'); const EventTime = require('./event-time'); +const Queue = require('tiny-queue'); const codec = msgpack.createCodec(); codec.addExtPacker(0x00, EventTime, EventTime.pack); @@ -35,7 +36,7 @@ class FluentSender { this._timeResolution = options.milliseconds ? 1 : 1000; this._socket = null; if (this._eventMode === 'Message') { - this._sendQueue = []; // queue for items waiting for being sent. + this._sendQueue = new Queue(); // queue for items waiting for being sent. this._flushInterval = 0; this._messageQueueSizeLimit = options.messageQueueSizeLimit || 0; } else { diff --git a/package.json b/package.json index f9c13ec..799d5f2 100644 --- a/package.json +++ b/package.json @@ -31,14 +31,15 @@ "node": ">=6" }, "dependencies": { - "msgpack-lite": "*" + "msgpack-lite": "*", + "tiny-queue": "^0.2.1" }, "devDependencies": { "async": "*", "chai": "*", "eslint": "^5.1.0", "eslint-plugin-node": "*", - "mocha": "*", + "mocha": "^6.0.0", "selfsigned": "*", "winston": "*" }, diff --git a/test/test.queue-performance.js b/test/test.queue-performance.js new file mode 100644 index 0000000..347d520 --- /dev/null +++ b/test/test.queue-performance.js @@ -0,0 +1,58 @@ +/* eslint-disable no-console */ +'use strict'; +/* globals describe, it */ +/* eslint node/no-unpublished-require: ["error", {"allowModules": ["chai"]}] */ +const expect = require('chai').expect; +const Queue = require('tiny-queue'); + +describe('queue performance', () => { + it('should be more than 100 times faster than array for large lengths', () => { + const array = []; + const queue = new Queue(); + for (let i = 1; i < 100000; i++) { + array.push(i); + queue.push(i); + } + + + const startQueue = process.hrtime(); + while (queue.length > 0) { + queue.shift(); + } + const totalQueue = process.hrtime(startQueue); + const startArray = process.hrtime(); + while (array.length > 0) { + array.shift(); + } + const totalArray = process.hrtime(startArray); + + console.log(`Array time: ${totalArray[0] + totalArray[1] / 1e9}`); + console.log(`Queue time: ${totalQueue[0] + totalQueue[1] / 1e9}`); + expect(totalArray[0] + totalArray[1] / 1e9 > (totalQueue[0] + totalQueue[1] / 1e9) * 100).to.be.true; + }); + + it('the time difference between array.shift and queue.shift should be irrelevant for small lengths', () => { + const array = []; + const queue = new Queue(); + for (let i = 1; i < 10000; i++) { + array.push(i); + queue.push(i); + } + + + const startQueue = process.hrtime(); + while (queue.length > 0) { + queue.shift(); + } + const totalQueue = process.hrtime(startQueue); + const startArray = process.hrtime(); + while (array.length > 0) { + array.shift(); + } + const totalArray = process.hrtime(startArray); + + console.log(`Array time: ${totalArray[0] + totalArray[1] / 1e9}`); + console.log(`Queue time: ${totalQueue[0] + totalQueue[1] / 1e9}`); + expect(totalArray[0] + totalArray[1] / 1e9 - (totalQueue[0] + totalQueue[1] / 1e9) < 0.001).to.be.true; + }); +}); \ No newline at end of file diff --git a/test/test.sender.js b/test/test.sender.js index 3d7bc45..f6056af 100644 --- a/test/test.sender.js +++ b/test/test.sender.js @@ -960,9 +960,9 @@ let doTest = (tls) => { s.emit('message3', {}); s.emit('message4', {}); expect(s._sendQueue.length).to.be.equal(3); - expect(s._sendQueue[0].tag).to.be.equal('debug.message2'); - expect(s._sendQueue[1].tag).to.be.equal('debug.message3'); - expect(s._sendQueue[2].tag).to.be.equal('debug.message4'); + expect(s._sendQueue.shift().tag).to.be.equal('debug.message2'); + expect(s._sendQueue.shift().tag).to.be.equal('debug.message3'); + expect(s._sendQueue.shift().tag).to.be.equal('debug.message4'); done(); }); });