$ time node nextTick.js
real 0m0.344s
user 0m0.276s
sys 0m0.067s
$ time node setTimeout.js
real 0m9.125s
user 0m8.707s
sys 0m0.410s
Feel free to fork and add your results!
for (var i = 0; i < 1024 * 1024; i++) { | |
process.nextTick(function () { Math.sqrt(i) } ) | |
} |
for (var i = 0; i < 1024 * 1024; i++) { | |
setTimeout(function () { Math.sqrt(i) }, 0) | |
} |
$ uname -a
Darwin MacBook-Air-13.local 11.4.0 Darwin Kernel Version 11.4.0: Mon Apr 9 19:32:15 PDT 2012; root:xnu-1699.26.8~1/RELEASE_X86_64 x86_64
$ node -v
v0.8.0
$ time node nextTick.js
real 0m0.833s
user 0m0.714s
sys 0m0.117s
$ time node setTimeout.js
real 0m2.600s
user 0m2.312s
sys 0m0.211s
intel core i5 @2.4 GHZ $ node -v v0.8.2
for (var i = 0; i < 1024 * 1024; i++) {
process.nextTick(function () { Math.sqrt(i) } )
}
$ time node nextTick.js
real 0m0.654s
user 0m0.576s
sys 0m0.076s
for (var i = 0; i < 1024 * 1024; i++) {
setTimeout(function () { Math.sqrt(i) }, 0)
}
$ time node setTimeout.js
real 0m1.740s
user 0m1.608s
sys 0m0.140s
var batch = 128;
for (var i = 0; i < 1024 * 1024; i+= batch) {
(function(i) {
setTimeout(function () {
for (var j = i; j<i+batch; j += 1) {
Math.sqrt(j)
}
}, 0)
})(i);
}
$ time node setTimeoutBatch.js
real 0m0.094s
user 0m0.084s
sys 0m0.008s
for (var i = 0; i < 1024 * 1024; i += 1) {
Math.sqrt(i)
}
$ time node forLoop.js
real 0m0.049s
user 0m0.044s
sys 0m0.000s
Seems that setTimeout(fn, 0) is not so bad if used more efficient.
What's the point of doing
for (var i=0; i<1<<20; i++)
async(function() { Math.sqrt(1<<20); });
Seems someone has forgotten a closure, to extract a root from very many integers you would do
for (var i=0; i<1<<20; i++)
async( Math.sqrt.bind(Math, i) );
$ uname -a
Linux ### 3.5.0-26-generic #42-Ubuntu SMP Fri Mar 8 23:18:20 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
$ node -v
v0.8.22
$ time node nextTick.js
real 0m0.787s
user 0m0.704s
sys 0m0.088s
$ time node setTimeout.js
real 0m2.874s
user 0m2.708s
sys 0m0.208s
$ uname -a
Darwin Lourenzo-Mac-Mini.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 i386 Macmini6,1 Darwin
$ node -v
v0.10.15
$ time node nextTick.js
real 0m0.650s
user 0m0.505s
sys 0m0.074s
$ time node setTimeout.js
real 0m1.067s
user 0m0.985s
sys 0m0.086s
"setTimeout" usually has built-in minimal delay value (which is a few ms). Even if you call "setTimeout" with 0 ms delay it will still run with at least with few ms delay. This is an another reason why it is so slow in these "benchmarks".
See: https://developer.mozilla.org/en/docs/Web/API/window.setTimeout#Notes
400 MHz ARM926EJ-STM ARM® Thumb® Processor
32 Kbytes Data Cache, 32 Kbytes Instruction Cache, MMU
[root@alarm ~]# uname -a
Linux alarm 3.1.0-g6853fe7 #6 PREEMPT Tue Mar 4 21:53:22 CST 2014 armv5tejl GNU/Linux
[root@alarm ~]# node -v
v0.10.26
[root@alarm ~]# time node nextTick.js
real 0m47.661s
user 0m46.309s
sys 0m1.352s
[root@alarm ~]# time node setTimeout.js
real 2m10.043s
user 2m4.707s
sys 0m5.332s
Is expected this result on arm platform?
RAM 3.7 GiB
Processor Intel® Core™ i5-2467M CPU @ 1.60GHz × 4
Arch 64-bit
OS Linux, Ubuntu 13.10
$ time node nextTick.js
real 0m0.749s
user 0m0.630s
sys 0m0.089s
$ time node setTimeout.js
real 0m1.294s
user 0m1.223s
sys 0m0.080s
RAM: 4 GiB
Proc: [email protected]
OS: Win 7x64
$ time node benchmark/nextTick.js
real 0m0.843s +/- 0.078
user 0m0.015s
sys 0m0.016s
$ time node benchmark/setTimeout.js
real 0m1.468s +/- 0.048
user 0m0.000s
sys 0m0.015s
Ubuntu-14.04
node -v: v0.10.35
$ time node nextTick.js
0.42s user 0.04s system 99% cpu 0.465 total
$ time node setTimeout.js
1.08s user 0.23s system 100% cpu 1.306 total
😄 👍
$ time node nextTick.js && time node setTimeout.js
real 0m1.044s
user 0m0.933s
sys 0m0.120s
real 0m1.499s
user 0m1.420s
sys 0m0.117s
Meh.
Can someone explain why there is a difference? In fact, I am facing an issue where setTimeout(f, 0)
and process.nextTick(f)
behave entirely different. Within a loop, the first will work as expected, whilst the second appears to not work.
Ubuntu 15.10 (VMWare player)
6 cpu | E5-1650 @ 3.2
Node 5.0.0
Average results after 3 runs
(With other node processes opened)
$ time node nextTick.js
real 0m0.924s
user 0m0.584s
sys 0m0.348s
$ time node setTimeout.js
real 0m0.732s
user 0m0.608s
sys 0m0.124s
(No ther node processes opened)
$ time node nextTick.js
real 0m0.800s
user 0m0.736s
sys 0m0.072s
$ time node setTimeout.js
real 0m0.714s
user 0m0.644s
sys 0m0.076s
I think you must compare setTimeout(fn, 0)
to setImmediate(fn)
, but I think setImmediate
will be still a bit faster.
$ uname -a
Darwin Wind.local 15.4.0 Darwin Kernel Version 15.4.0: Fri Feb 26 22:08:05 PST 2016; root:xnu-3248.40.184~3/RELEASE_X86_64 x86_64
$ node -v
v5.0.0
$ time node nextTick.js
real 0m0.761s
user 0m0.691s
sys 0m0.075s
$ time node setTimeout.js
real 0m0.728s
user 0m0.657s
sys 0m0.074s
$ time node setImmediate.js
real 0m0.682s
user 0m0.621s
sys 0m0.064s
@ismoura No much difference right?
$ uname -a
Linux 4.7.0-040700-generic #201608021801 SMP Tue Aug 2 22:03:09 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04
Codename: xenial
$ node -v
v6.4.0
$ time node nextTick.js
real 0m2.449s
user 0m2.252s
sys 0m0.124s
$ time node setTimeout.js
real 0m2.693s
user 0m1.604s
sys 0m0.156s
Using let
$ time node nextTick.js
real 0m2.875s
user 0m2.768s
sys 0m0.156s
$ time node setTimeout.js
real 0m2.305s
user 0m2.128s
sys 0m0.108s
Using var
$ time node nextTick.js
real 0m2.300s
user 0m2.256s
sys 0m0.088s
$ time node setTimeout.js
real 0m1.699s
user 0m1.588s
sys 0m0.108s
RAM 8G
core 2
time node nexttick.js
real 0m0.863s
user 0m0.795s
sys 0m0.089s
time node timeoutqps.js
real 0m1.084s
user 0m0.978s
sys 0m0.111s
Darwin Kernel Version 16.3.0: Thu Nov 17 20:23:58 PST 2016; root:xnu-3789.31.2~1/RELEASE_X86_64 x86_64
node v7.2.0
node nextTick.js 0.62s user 0.12s system 99% cpu 0.747 total
node setTimeout.js 0.70s user 0.11s system 98% cpu 0.821 total
@IngwiePhoenix The explanation is here: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#process-nexttick-vs-setimmediate
process.nextTick()
allows you to "starve" your I/O events. setImmediate
is safer.
$ uname -a
Darwin MacBook-Pro.local 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64
$ node -v
v12.11.1
$ time node nextTick.js
node nextTick.js 0.52s user 0.12s system 189% cpu 0.338 total
$ time node setTimeout.js
node setTimeout.js 1.09s user 0.12s system 128% cpu 0.938 total
on ubuntu virtual machine
time node nextTick.js
real 0m0.669s
user 0m0.487s
sys 0m0.357s
time node setTimeout.js
real 0m1.513s
user 0m1.709s
sys 0m0.090s
node nextTick.js 3.11s user 0.24s system 93% cpu 3.587 total
node setTimeout.js 31.21s user 1.59s system 89% cpu 36.616 total
This kills the Atom processor.