-
Notifications
You must be signed in to change notification settings - Fork 7.3k
emitter.listeners('ev') should return a copy, not the actual array #3442
Comments
+1 +1 +1 +1 |
Foretold in the docs on e72addc. |
032fc42 changed readline.js to be compatible with this change, however doesn't copying the array introduce an extra overhead for when only the length of the array is required? Perhaps a separate |
I think the listenerCount idea might be a bit misleading. Considering that listenerCount may not be consistent with the length of a copied array. The overhead of making a shallow copy of the array seems minimal to me vs the potential for inconsistent data. |
@joeandaverde: Slightly confused... how would there be inconsistent data? Your probably correct as I don't know too much about Node internals, but shouldn't |
You are correct indeed. Consider this: listeners = emitter.listeners('foo') if you're iterating over the listeners array with the count retrieved from emitter.listenerCount then the size MAY not correspond with the size of listeners.length. There's just more source for confusion when accessing the size of the array separately from the actual array. |
My |
Fixed in 20e12e4. |
I agree with adammw. There are times when having this overhead is unnecessary. Another example would be if you just want to check if a particular listener currently exists for some event. You shouldn't be forced to obtain a whole new copy of the listeners array just to determine this. If this commit is here to stay, would pull requests be accepted to incorporate into EventEmitter some additional functions that operate directly on the original array to reduce overhead (e.g. emitter.hasListener('event', listener))? Or heck, how about a function that does return the original reference to the array (e.g. emitter.listenersRef('event') or emitter.listeners('event', true)) instead? |
No. It reeks of premature optimization. Conclusively demonstrate a big performance drop-off in a real-world scenario first. |
@bnoordhuis ++. Show that this is a real problem, and we'll decide how to address it. Until then, we're going to decide not to address it. |
Makes sense not to fix anything that isn't broken, I was just trying to pitch in any possible optimisations I could see. I've tried to benchmark if there is any difference (https://gist.github.com/3759971), and the result was about ~50ms difference over 1000000 events, but I'm not sure if they are valid because perhaps my test isn't actually written to test it correctly. For reference the I personally prefer my original idea of having a removedListener event (#3243) as I predict that it would have even less overhead as it doesn't need to check for listeners upon every emitted data, it just gets told when it needs to check. |
I added a |
Now |
@adammw I seriously doubt that it makes any difference one way or the other. That functions gets called maybe ten times a second (if you're a really fast typist) and you never have more than one or two listeners. |
It makes a lot of headaches in many edge cases to expose a reference to the listeners array.
It would be better if
emitter.listeners('ev')
returned a copy of the array, not the actual thing. Then we could change it, without worrying about consistency guarantees or breaking userland code.The text was updated successfully, but these errors were encountered: