Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTimeout in javascript make function run faster

I have an application which I have to push a lot values to array, so I test the execution time:

var st = new Date().getTime();
var a = [];
for (var i = 0; i < 20971520; i++) {
  a.push(i);
}
var ed = new Date().getTime();
console.info((ed - st) / 1000);
console.info(a.length);

I run the codes in Firefox Console and Chrome console directly, and it cost 37 seconds. And during the execution, even the mouse can be moved in Chrome, but there is no interactive effect.

Then I change the codes:

function push() {
  var st = new Date().getTime();
  var a = [];
  for (var i = 0; i < 20971520; i++) {
    a.push(i);
  }
  var ed = new Date().getTime();
  console.info((ed - st) / 1000);
  console.info(a.length);
}

var tr = setTimeout(push, 50);

Simplify put the codes in a function, and call it using the setTimeout, it cost 0.844 second. And during the execution, I can operation in Chrome normally.

Screenshot of console

What's going on here?

I know that the setTimeout will put the control to the browser to do the UI job, which will make the page responsive. For example, when I do some calculation during the mousemove of the page, I would put the calculation executed delayed to prevent it blocking the UI.

But why it reduce the total execution time of the same codes?

like image 287
hguser Avatar asked Jan 06 '15 08:01

hguser


2 Answers

And during the execution, I can operation in Chrome normally.

Not true. The main chrome window will be just as frozen as the other case (just for a shorter while). The debug tools are a separate thread and will not slow down though.

But why it reduce the total execution time of the same codes?

It does if you run in dev tools. If you execute the code in actuality where the VM can make property optimizations the times are comparable (nearly 1 second). e.g.

   var st = new Date().getTime();
   var a = [];
   for (var i = 0; i < 20971520; i++) {
       a.push(i);
   }
   var ed = new Date().getTime();
   console.info('normal', (ed - st) / 1000);
   console.info(a.length);

   function push() {
       var st = new Date().getTime();
       var a = [];
       for (var i = 0; i < 20971520; i++) {
           a.push(i);
       }
       var ed = new Date().getTime();
       console.info('timeout', (ed - st) / 1000);
       console.info(a.length);
   }

   var tr = setTimeout(push, 0);

http://jsfiddle.net/gu9Lg52j/ you will see the normal executes just as fast as setTimeout.

Also if you wrap the code in a function and execute in a console the time will be comparable even without a setTimeout as the VM can make optimizations between function definition and execution:

  function push() {
       var st = new Date().getTime();
       var a = [];
       for (var i = 0; i < 20971520; i++) {
           a.push(i);
       }
       var ed = new Date().getTime();
       console.info('timeout', (ed - st) / 1000);
       console.info(a.length);
   }
   push();
like image 53
basarat Avatar answered Sep 30 '22 13:09

basarat


Both variations of code should run with almost identical speed (the latter example might be faster but not 10 times faster).

Inside the Chrome developer tools, there is a different story. The expressions are evaluated inside a with block. This means the variables such as a and i are first searched inside another object (the __commandLineAPI). This adds an additional overhead which results in the 10 times longer execution time.

like image 26
Salman A Avatar answered Sep 30 '22 14:09

Salman A