Create a gist now

Instantly share code, notes, and snippets.

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)
}
@denis-sokolov

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

@mmalecki
Owner

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

@denis-sokolov

0.6.8 here. :)

@mingder78

$ 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

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

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
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
@alexbardas
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

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
Unknown 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

@lourenzo

$ 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

@mcharytoniuk

"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

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?

@eliranmal

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

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
@vireshas

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

@siyangYao

😄 👍

@ninjadoge24
$ 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.

@IngwiePhoenix

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

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

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

@lsmoura
$ 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
@MadebyAe

@ismoura No much difference right?

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