joyent/node — pull request #8131 by JacksonTian (2014-08-11 08:47:45+00:00)
Title: lib: don't use emitter.listeners(type).length

The `EventEmitter.listenerCount(event)` is faster than `emitter.listeners(type).length`. If just want get the listener count of event, but don't use the listeners, use `EventEmitter.listenerCount(event)` is better.

following is my benchmark scripts:

```
var Benchmark = require('benchmark');
var EventEmitter = require('events').EventEmitter;

var suite = new Benchmark.Suite;
var EE0 = new EventEmitter();
var EE1 = new EventEmitter();
EE1.on('eventname', function () {});
var EE2 = new EventEmitter();
EE2.on('eventname', function () {});
EE2.on('eventname', function () {});
var EE3 = new EventEmitter();
EE3.on('eventname', function () {});
EE3.on('eventname', function () {});
EE3.on('eventname', function () {});
var EE4 = new EventEmitter();
EE4.on('eventname', function () {});
EE4.on('eventname', function () {});
EE4.on('eventname', function () {});
EE4.on('eventname', function () {});

// add tests
suite.add('0: EventEmitter.listenerCount', function() {
return EventEmitter.listenerCount(EE0, 'eventname');
})
.add('0: emitter.listeners(type).length', function() {
return EE0.listeners('eventname').length;
})
// add tests
suite.add('1: EventEmitter.listenerCount', function() {
return EventEmitter.listenerCount(EE1, 'eventname');
})
.add('1: emitter.listeners(type).length', function() {
return EE1.listeners('eventname').length;
})
// add tests
suite.add('2: EventEmitter.listenerCount', function() {
return EventEmitter.listenerCount(EE2, 'eventname');
})
.add('2: emitter.listeners(type).length', function() {
return EE2.listeners('eventname').length;
})
// add tests
suite.add('3: EventEmitter.listenerCount', function() {
return EventEmitter.listenerCount(EE3, 'eventname');
})
.add('3: emitter.listeners(type).length', function() {
return EE3.listeners('eventname').length;
})
// add tests
suite.add('4: EventEmitter.listenerCount', function() {
return EventEmitter.listenerCount(EE4, 'eventname');
})
.add('4: emitter.listeners(type).length', function() {
return EE4.listeners('eventname').length;
})
// add listeners
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
// run async
.run({ 'async': true });
```

Result:

```
$ node count.js
0: EventEmitter.listenerCount x 5,747,107 ops/sec ±2.08% (88 runs sampled)
0: emitter.listeners(type).length x 5,506,623 ops/sec ±2.60% (81 runs sampled)
1: EventEmitter.listenerCount x 26,523,395 ops/sec ±2.58% (90 runs sampled)
1: emitter.listeners(type).length x 20,293,218 ops/sec ±4.55% (78 runs sampled)
2: EventEmitter.listenerCount x 24,951,134 ops/sec ±0.96% (89 runs sampled)
2: emitter.listeners(type).length x 6,925,280 ops/sec ±1.14% (91 runs sampled)
3: EventEmitter.listenerCount x 24,448,320 ops/sec ±1.71% (90 runs sampled)
3: emitter.listeners(type).length x 6,876,485 ops/sec ±1.77% (84 runs sampled)
4: EventEmitter.listenerCount x 24,822,554 ops/sec ±1.95% (89 runs sampled)
4: emitter.listeners(type).length x 6,191,708 ops/sec ±2.01% (83 runs sampled)
Fastest is 1: EventEmitter.listenerCount
```
if listener count more than 1, `EventEmitter.listenerCount` 4x faster than `emitter.listeners(type).length`.