Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
process.nextTick vs setTimeout(fn, 0)
for (var i = 0; i < 1024 * 1024; i++) {
process.nextTick(function () { Math.sqrt(i) } )
}

Results

Intel i7 890 @ 2.93 GHz x64, node compiled with -march=native -mtune=native:

$ 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++) {
setTimeout(function () { Math.sqrt(i) }, 0)
}

Curious. Although the point stands, mine difference is ~4 times smaller:

real 0m0.650s
user 0m0.492s
sys 0m0.072s

real 0m5.374s
user 0m5.028s
sys 0m0.412s

Owner
mmalecki commented Feb 2, 2012

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).

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

xkizer commented May 28, 2012

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

danneu commented Jun 12, 2012

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.

tp commented Jun 30, 2012
$ 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.

bergus commented Dec 13, 2012

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) );
@ghost
ghost commented Mar 28, 2013

$ 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

dvdvck commented Mar 15, 2014

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
syzer commented Jul 30, 2014

RAM: 4 GiB
Proc: i5-M460@2.53
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

😄 👍

@ghost
ghost commented Jun 28, 2015
$ 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.

fed135 commented Dec 4, 2015

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
rafis commented Dec 9, 2015

I think you must compare setTimeout(fn, 0) to setImmediate(fn), but I think setImmediate will be still a bit faster.

lsmoura commented Mar 24, 2016
$ 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?

shivarajnaidu commented Aug 26, 2016 edited
$ 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
slclub commented Jan 12, 2017

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
yorts52 commented Jan 13, 2017

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment