-
Notifications
You must be signed in to change notification settings - Fork 29.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
timers: refactor timer list processing #18582
Conversation
CI: https://ci.nodejs.org/job/node-test-pull-request/12956/ |
Benchmark results:
Nice bump on the |
940ef38
to
3a8933c
Compare
Instead of using kOnTimeout index to track a special list processing function, just pass in a function to C++ at startup that executes all handles and determines which function to call. This speeds up unpooled timeouts, as well as cleaning up timers.
3a8933c
to
854720a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
// then measures their execution on the next uv tick | ||
|
||
const bench = common.createBenchmark(main, { | ||
millions: [1], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally do not like the "millions" and would actually like to replace those with e.g. n
over time but that might only be my view on it. It is at least for me easier to read how many operations got executed that way instead of having to see that the output is actually also in millions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback. Changed over to n = 1e6
.
setTimeout(i % 2 ? cb : cb2, 1).unref().ref(); | ||
} | ||
|
||
bench.start(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally feel like it would also be better to move the start above the loop to include that time in the benchmark as I would say the creation time is important as well. But I guess you explicitly wanted to only measure the execution time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we have other tests that check the creation time. This way there's less noise in assessing the execution time.
Hi @nodejs/collaborators — could you please review this timers PR? It's been a little while and I would like to get some reviews so it can be improved or land. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks everyone. Landed in 0f9efef |
Instead of using kOnTimeout index to track a special list processing function, just pass in a function to C++ at startup that executes all handles and determines which function to call. This change improves the performance of unpooled timeouts by roughly 20%, as well as makes the unref/ref processing easier to follow. PR-URL: #18582 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com>
Should this be backported to |
Instead of using kOnTimeout index to track a special list processing function, just pass in a function to C++ at startup that executes all handles and determines which function to call. This change improves the performance of unpooled timeouts by roughly 20%, as well as makes the unref/ref processing easier to follow. PR-URL: nodejs#18582 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com>
Opting to not land on v8.x, please lmk if we should reconsider |
(
The first commit is from #18579. I will rebase once that PR lands.Rebased.)Currently timer handles have their processing function stored at
kOnTimeout
(which is an index = 0). This isn't actually completely efficient, even if the function is declared on theprototype
, as it requires replacing whenunref
is called and un-assigning it when clearing timeouts. It also requires a property lookup in C++ which is a tad slow.Instead, it's possible to pass in a function from JS to C++ at startup, similar to how Immediates work currently, which is then called from C++ and that function then decides what to do further (that is, whether to call
listOnTimeout
orunrefdHandle
).Locally, this change yields a roughly 10% improvement on the newly introduced benchmark for unpooled execution.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
benchmark, timers