Skip to content

Commit

Permalink
lib: micro-optimize EventEmitter#removeListener()
Browse files Browse the repository at this point in the history
Replace the call to Array#splice() with a faster open-coded version
that creates less garbage.

Add a new benchmark to prove it.  With the change applied, it scores
a whopping 40% higher.

PR-URL: #185
Reviewed-By: Chris Dickinson <[email protected]>
  • Loading branch information
bnoordhuis committed Dec 20, 2014
1 parent d0c238c commit d3f8db1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
23 changes: 23 additions & 0 deletions benchmark/events/ee-add-remove.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var common = require('../common.js');
var events = require('events');

var bench = common.createBenchmark(main, {n: [25e4]});

function main(conf) {
var n = conf.n | 0;

var ee = new events.EventEmitter();
var listeners = [];

for (var k = 0; k < 10; k += 1)
listeners.push(function() {});

bench.start();
for (var i = 0; i < n; i += 1) {
for (var k = listeners.length; --k >= 0; /* empty */)
ee.on('dummy', listeners[k]);
for (var k = listeners.length; --k >= 0; /* empty */)
ee.removeListener('dummy', listeners[k]);
}
bench.end(n);
}
9 changes: 8 additions & 1 deletion lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ EventEmitter.prototype.removeListener =
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
spliceOne(list, position);
}

if (this._events.removeListener)
Expand Down Expand Up @@ -318,3 +318,10 @@ EventEmitter.listenerCount = function(emitter, type) {
ret = emitter._events[type].length;
return ret;
};

// About 1.5x faster than the two-arg version of Array#splice().
function spliceOne(list, index) {
for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
list[i] = list[k];
list.pop();
}

0 comments on commit d3f8db1

Please sign in to comment.