Uh oh!
There was an error while loading. Please reload this page.
Improve performance of event and timer interfaces - #406
Conversation
mscdex
commented
Jan 14, 2015
+10 |
jbergstroem
commented
Jan 14, 2015
@RubenVerborgh: It's somewhat interesting that setImmediate seems to be slower than in nodejs. Did you stumble on anything while researching this that would explain why? |
RubenVerborgh
commented
Jan 14, 2015
@jbergstroem I've only looked at the JavaScript level, which has remained unchanged. It must have something to do with one of the underlying layers. Note that setImmediate was quite slow in Node 0.10.x, so something has happened to make it faster in the current master. |
RubenVerborgh
commented
Jan 15, 2015
Thinking about this some more, it seems that io.js did not implement the patch that made one-listener events in Node slower after v0.10.x. I wonder if that same patch is responsible for the other differences. |
RubenVerborgh
commented
Jan 19, 2015
Rebased on v1.x to resolve a merge conflict. |
There was a problem hiding this comment.
This is a typical de-opt; I wonder how much difference it makes already not having this.
There was a problem hiding this comment.
There will already be some difference for sure. But why stop there, if the other cases show an improvement by using the switch as well?
Fishrock123
commented
Jan 24, 2015
SGTM Little odd to me that |
XadillaX
commented
Jan 24, 2015
so you are somewhat like this way: https://github.com/XadillaX/Toshihiko/blob/develop/util/damnarguments.js and https://github.com/XadillaX/Toshihiko/blob/develop/util/damnargumentsgenerator.js. maybe you can try more arguments. |
RubenVerborgh
commented
Jan 24, 2015
@Fishrock123 Slower? @XadillaX 2 seems like a good number to stop. Events with more arguments are rare. Plus there is a slight overhead in allocating the variables, as they are used in a closure. (Also, I'd suggest to convert the long chain of |
Fishrock123
commented
Jan 24, 2015
I mean slower than |
RubenVerborgh
commented
Jan 24, 2015
@Fishrock123 No meaningful comparison is possible between different tests; they only allow comparing the performance of different io.js versions for the same test. The number of repetitions for each test was chosen such that their timings were roughly in the 1–10 second range. |
There was a problem hiding this comment.
switch to Array.isArray()?
There was a problem hiding this comment.
Fine with me; is there a guideline for such decisions in general? I followed the existing convention in the file.
There was a problem hiding this comment.
I just noted during rebasing that the conflicts are due to code changes moving away from util operations. So I'll do this in general.
brendanashworth
commented
Feb 8, 2015
I like what this PR is getting at and I'd certainly like to see it merged in. Looks like it needs a rebase though. |
RubenVerborgh
commented
Feb 9, 2015
Here you go, rebased on v1.x. |
RubenVerborgh
commented
Feb 24, 2015
…and rebased again. @mscdex might want to check whether the optimizations from b677b84 are relevant here as well. One of my original commits was not necessary anymore after b677b84. |
There was a problem hiding this comment.
could you put the unassigned variables (args, i) in front of the assigned ones?
brendanashworth
commented
Feb 26, 2015
Right now the code looks good to me but I have yet to run tests (with the libuv issue for 1.4 I can't properly test) so I'm not gonna officially sign off on this until tomorrow when they have that fixed. By the way, I think we'd be happy to have your benchmarks added into the repository. I'd shepherd in a pull request for those if you'd be willing to patch them into how we do them here. @Fishrock123 was your SGTM a sign-off or just a +1? |
brendanashworth
commented
Feb 28, 2015
I got the tests to pass. However I'm not really seeing any improvement on the |
RubenVerborgh
commented
Feb 28, 2015
Confirmed that the event emitter improvements no longer make a difference, due to b677b84. Will remove the commit in question if needed. |
brendanashworth
commented
Mar 4, 2015
Yeah, if the commit no longer makes a difference I'd remove it. I'll run your benches for the timers to test performance before I give my official sign off. Since this pull request deals with timers, a locked API, I can't be the sole signee to be sure this wouldn't have consequences I don't see. Summoning @iojs/collaborators |
There was a problem hiding this comment.
I prefer var len = arguments.length; on a different line. single assignation per line, and all unused variable on another. :)
trevnorris
commented
Mar 4, 2015
Left a couple comments, and the commits squashed, and their messages cleaned up, but LGTM otherwise. |
RubenVerborgh
commented
Mar 4, 2015
@trevnorris Please detail what you mean with “messages cleaned up”. Just one commit then with “Improve timer performance?” |
trevnorris
commented
Mar 4, 2015
@RubenVerborgh Squashed, the message should read |
RubenVerborgh
commented
Mar 4, 2015
Squashed and commit message edited. |
There was a problem hiding this comment.
len = arguments.length on it's own line?
tellnes
commented
Mar 4, 2015
One comment, otherwise LGTM. |
This pull request speeds up multi-listener event callbacks,
setImmediate,setTimeout, andsetIntervalby differentiating between zero-, one-, and two-argument callbacks. This technique was previously only applied to single-listener event callbacks—and even they have been sped up.Current situation
The
EventEmitter#emitcode has special cases for zero-, one-, and two-argument callbacks as follows:Improvements in this pull request
On the one hand, this pull request speeds up this technique by avoiding the use of
argumentsindexing, instead adding actual function argumentsarg1andarg2.On the other hand, this pull request also applies the same technique to listeners with multiple callbacks, as well as the timer functions
setImmediate,setTimeout, andsetInterval.Below are my results of performance tests that examine these cases (ran on a 2010 MacBook Pro).
Considerations
Given the importance of callbacks in io.js, delivering maximum performance for common cases is crucial. The only drawback of this pull request seems to be the increased code length; but it brings consistency since the optimization technique was previously only applied to one particular case (and slightly suboptimally).
I added each change in a different commit, so you can decide which ones to merge. All commits are independent of each other, except for the second, which depends on the first.
If you want these commits squashed, or applied to a different branch, please let me know and I'll do so.
PS This pull request is the equivalent of nodejs/node-v0.x-archive#9007.