$ 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) | |
} |
0.6.8 here. :)
$ time node nextTick.js
real 0m0.534s
user 0m0.467s
sys 0m0.069s
$ time node setTimeout.js
real 0m10.724s
user 0m10.163s
sys 0m0.678s
on my 13" Air
Intel(R) Core(TM)2 Duo CPU E7400 @ 2.80GHz
node v0.6.17
$ time node nextTick.js
real 0m0.622s
user 0m0.532s
sys 0m0.084s
$ time node timeOut.js
real 0m11.111s
user 0m10.273s
sys 0m0.636s
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.
$ 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
That's interesting. I bet intervals just got faster - I ran my tests at a pretty old version of node. Too bad I didn't specify it (I don't actually remember it right now).