1

The following code uses setInterval to increment tick once every 16ms and logs out the number of ticks per second. I'm expecting this to report ~60 ticks per second (as 1000ms / 16ms = ~60) but instead I'm seeing about 35-40. This is on a powerful windows desktop under minimal load (node v14.5.4). Running the same code in the browser produces the expected results.

let lastTick = 0;
let tick = 0;

setInterval(()=>{
    tick++;
}, 16);

setInterval(()=>{
    console.log("ticks per second: " + (tick-lastTick));
    lastTick = tick;
}, 1000);

What am I missing?

Update

So running with node --inspect and then profiling the javascript boosts the values up 60 per second, but only while the profiler is running. Must be some sort of strange CPU throttling on low CPU processes, but I can't find any cause.

  • 2
    First of all, [the timers *aren't* precise](https://stackoverflow.com/questions/29971898/how-to-create-an-accurate-timer-in-javascript). Take the timeout delay as the *minimum*. Second, is there any other heavy operations happening? – VLAZ Jan 29 '21 at 17:38
  • Your code is fine. I tested it on my machine and it is printing `60` and `61` in a row. You have to check other processes in your machine. – Mahdi Aryayi Jan 29 '21 at 17:41
  • Thanks for the edit. The code is the only thing running; literally the above copy pasted into timer.js and then run with `node timer` on a i9-9990k. It's running pretty much a full 10ms slower per interval than I'd expect, I know Node doesn't have great precision, but this seems extreme! – Automaton.systems Jan 29 '21 at 17:45
  • It's so odd that the browser is happily giving me 60 per second but node is only hitting 40 per second . – Automaton.systems Jan 29 '21 at 17:47

1 Answers1

1

I cannot prove this, but anecdotally Chrome seem to perform reasonably reliably for intervals in the tens of ms range because it is performing more work (rendering pages, reading user input etc) and so doesn't fall foul of CPU Scheduling and missing the 'correct' time window for the setInterval tick. Node which isn't doing very much beyond running the code provided regularly gets de-scheduled and therefore misses it's interval.

This theory is supported by the fact that increasing the work that node is doing (ie running the profiler or adding more unrelated work between ticks) improves the frequency of the setInterval ticks.

As node has no reliable timing function in the ms range (aside from running a tight loop with setImmediate) I've offloaded the timing work to another system.