Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute code exactly 1000 times in 1 second in JavaScript

n = 0;
var timer = setInterval(function() {
    if (n == 0) {
        console.log(new Date());
    }
    // execute some other code here
    n++;
    if (n == 1000) {
        clearInterval(timer);
        console.log(new Date());
    }
}, 1);

This code executes in about 3-4 seconds, depending on machine and browser maybe. How can I make it execute in exactly 1 second?

like image 800
Jswq Avatar asked Dec 25 '15 04:12

Jswq


People also ask

What is faster than for loop in JavaScript?

forEach loop The forEach method in Javascript iterates over the elements of an array and calls the provided function for each element in order. The execution time of forEach is dramatically affected by what happens inside each iteration. It is fast and designed for functional code.

How do you write a function after 2 seconds?

Setting up code to run later # The setTimeout() method accepts two arguments: the function to run, and how long to wait (in milliseconds) before running it. setTimeout(function () { console. log('I will run after 2 seconds'); }, 2000);


2 Answers

Javascript timers in browsers are inaccurate (C would be better for that usage).

However, you get a better averaged accuracy having the delay as high as possible, especially avoiding low values, like 1 ms.

It will be difficult to have 1000 evenly timed calls to a function, within one second. One millisecond being a low value , the simple execution of the triggered function itself (plus the overhead of handling timers) is likely to take a time close to 1 ms (or maybe more)... meaning the JS interpreter calls the function after 1ms, executes the code then set a new 1ms timer. Consequently there is more than 1ms between calls.

The JS interpreter does something like

At t   call function     <-- this takes
       execute function  <-- some 
at t+x set new 1ms timer <-- time
etc...

However if you can afford to end the process within a timeframe closer to 1 second (than the 3-4 seconds you have now), doing as many as possible 1 ms calls, this is possible.

var n = 0;

var timer= setInterval(function(){
          if(n++ == 0) {
                console.log(new Date());
          }
     }, 1);

setTimeout(function() {
         clearInterval(timer);
         console.log("Got n="+n+" at "+(new Date()));
     }, 1000);

This is basically the same program as yours

  • n is incremented every 1ms
  • however the end of the process is controlled by another 1-second timer

In Chrome, I get 252 n increments and the two dates are ~1 second apart.

like image 131
Déjà vu Avatar answered Oct 25 '22 13:10

Déjà vu


Here is a demonstration of the approach for one timer per iteration. It takes roughly 1 second to do 1000 "iterations" of the same callback. The design is rough as it is only an example.

jsFiddle Demo

//Function to compose the array of timers
function timers(count, callback){
  var timers = [];
  for(var i = 0; i < count; i++){
    timers.push(timer(callback,i));
  }
  return timers;
};
//Function to compose individual timer
function timer(callback, delay){
  return function(){
    setTimeout(callback,delay);
  };
};

//Usage
console.log("Start:",new Date()); //timestamp

var display = document.querySelector("#display");

var settings = { n : 0 };

display.innerHTML = settings.n;

//Arrange timers and callback
var set = timers(1000,function(){
    this.n++;
		display.innerHTML = this.n;
    if(this.n === 1000) console.log("End:",new Date());
}.bind(settings));

//Execute timers
for(var i = 0; i < set.length; i++){ set[i](); }
<div id="display">
</div>

All browsers handle this differently. In most browsers, especially chrome, the default smallest amount of time possible for a task to execute (as in using an interval or timeout) is 4 milliseconds.

The result of the 4ms window is that your 1000 iterations are being done in about 4 seconds. So, clearly this is longer than the desired 1 second in 1000 iterations.

There is not a desirable (possible?) way to accomplish an exact 1 millisecond iteration in JavaScript when executed in a modern browser. The best bet you would have if space (memory and processing power) were not an issue would be to create a timer for each iteration manually and then execute the entire set of them. This of course has its own issues, such as whether or not each task is even executed at the time it was supposed to.

like image 27
Travis J Avatar answered Oct 25 '22 15:10

Travis J