SetTimeout in javascript makes a function run faster

I have an application that I have to push to the array with multi-valued values, so I check the runtime:

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 the Firefox console and Chrome console, and it costs 37 seconds . And at runtime, 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 codes in a function and call it with setTimeout , it costs 0.844 second . And at runtime, I can work fine in Chrome.

Screenshothot of console

What's going on here?

I know that setTimeout will put the control in the browser to do the user interface job, which will make the page susceptible. For example, when I do some calculations during the mousemove page, I would set the calculation to be delayed to prevent the user interface from blocking it.

But why does this reduce the overall execution time of the same codes?

+5
source share
4 answers

And at runtime, I can work fine in Chrome.

Not true. The main chrome window will be as frozen as in the other case (only for a shorter time). Debugging tools are a separate thread and will not slow down.

But why does this reduce the overall execution time of the same codes?

This happens if you run dev tools. If you are actually executing the code when the virtual machine can perform property optimization, the time is comparable (almost 1 second). eg

  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 that normal is as fast as setTimeout .

Also, if you complete the code in the function and execute in the console, the time will be comparable even without setTimeout , since the virtual machine can do the optimization between the definition of the function and the 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(); 
+5
source

Both versions of the code should work at almost the same speed (the last example can be faster, but not 10 times faster).

Chrome developer tools have a different story. Expressions are evaluated inside the with block. This means that variables, such as a and i , are first looked up inside another object ( __commandLineAPI ). This adds extra overhead, which leads to an increase in execution time by 10 times.

+2
source

All JavaScript engines perform various optimizations. For example, V8 uses 2 compilers, simple by default and optimizing. Code not compiled by the optimizing compiler is slow, very slow.

The condition for starting the optimizing compiler is that the code must be in a (not too long) function ( other conditions exist ). The first code that you tried in the console does not work. Put your first code in a function and you will see that it works the same as the second, setTimeout does not change anything.

It does not make sense to check performance in the console when optimizing compilation is the main factor of efficiency. If you are targeting node, use the underlying platform. If you are targeting a browser, use a site such as jsperf .

Now that you need to do very long calculations in the browser (which seems to be wrong), you should consider using the web interface workers who do work in the background thread without affecting the user interface.

+1
source

setTimeout , as others have noted, does not speed up the creation of an array and blocks the browser. If you are concerned about blocking the browser during array creation, web workers (see MDN ) may come to the rescue. Below is a jsFiddle demonstration using a web worker for your code. The working code is inside html:

 onmessage = function (e) { var a = [], now = new Date; for (var i=0; i<20971520; i++) { a.push(i); } postMessage({timings: 'duration: '+(new Date()-now) + 'Ms, result: [' + a[0] + '...'+a[a.length-1] + ']'}); } 
0
source

Source: https://habr.com/ru/post/1210454/


All Articles