Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`await` Slower Than It Should Be In Chrome

While testing the performance of await, I uncovered a confounding mystery. I ran each of the following code snippets several times each in the console to filter out flukes, and took the average times of the relevant data.

(function(console){
    "use strict";
    console.time();
    var O = [1];
    for (var i=0; i !== 107000; ++i) {
        const O_0 = O[0];
        O[0] = O_0;
    }
    console.timeEnd();
})(console);

Resulting in: default: 5.322021484375ms

Next, I tried adding making it asynchronous

(async function(console){
    "use strict";
    console.time();
    var O = [1];
    for (var i=0; i !== 107000; ++i) {
        const O_0 = O[0];
        O[0] = O_0;
    }
    console.timeEnd();
})(console);

Nice! Chrome knows its stuff. Very low overhead: default: 8.712890625ms

Next, I tried adding await.

(async function(console){
    "use strict";
    console.time();
    var O = [1];
    for (var i=0; i !== 107000; ++i) {
        const O_0 = O[0];
        O[0] = await O_0;
    }
    console.timeEnd();
})(console);

This results in 100x speed reduction: default: 724.706787109375ms

So, there must be some logical reason, right? I tried comparing the types prior.

(async function(console){
    "use strict";
    console.time();
    var O = [1];
    for (var i=0; i !== 107000; ++i) {
        const O_0 = O[0];
        O[0] = typeof O_0 === "object" ? await O_0 : O_0;
    }
    console.timeEnd();
})(console);

Okay, so that is not it: default: 6.7939453125ms

So then, it must be the promise-part: checking to see if the item passed to await is a promise. That must be the culprit, am I right or am I right?

(async function(console, Promise){
    "use strict";
    const isPromise = Promise.prototype.isPrototypeOf.bind(Promise);
    console.time();
    var O = [1];
    for (var i=0; i !== 107000; ++i) {
        const O_0 = O[0];
        O[0] = isPromise(O_0) ? await O_0 : O_0;
    }
    console.timeEnd();
})(console, Promise);

This results in: default: 7.2041015625ms

Okay, okay, let us give Chrome the benefit of the doubt. Let us assume, for a second, that they programmed await far less than perfectly.

(async function(console, Promise){
    "use strict";
    const isPromise = Promise.prototype.isPrototypeOf.bind(Promise.prototype);
    console.time();
    var O = [1];
    for (var i=0; i !== 107000; ++i) {
        const isAnObject = typeof O[0] === "object" ? true : false;
        const isThisAPromise = isPromise(O[0]);
        O[0] = isAnObject && isThisAPromise ? await O[0] : O[0];
    }
    console.timeEnd();
})(console, Promise);

But even this fails to explain the poor performance of await: default:7.85498046875ms

Okay, honestly, I give up. I would think that await would be at least 100x faster than it is now. I cannot think of a single good reason why it would not be 100x faster in a perfect world. However, we do not live in a perfect world, so there inlies the question: how? How? How is it this slow? Is there any hope of it being any faster in the future (like maybe, say, around about 100x faster)? I am looking for facts and an objective analysis of this issue that would explain the puzzling mystery I am seeing in the above performance tests.

like image 656
Jack G Avatar asked Sep 07 '18 11:09

Jack G


People also ask

Is it better to use async await or then?

We recommend using async/await where possible, and minimize promise chaining. Async/await makes JavaScript code more accessible to developers that aren't as familiar with JavaScript, and much easier to read.

How do I use asynchronous?

async and await Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

Why is async so slow?

On a quick look, the results are expected: your async sum is using just one thread, while you asynchronously wait for it to finish, so it's slower than the multi-threaded sum. You'd use async in case you have something else to finish while it's doing its job.

When should you use async await?

Async/Await makes it easier to write promises. The keyword 'async' before a function makes the function return a promise, always. And the keyword await is used inside async functions, which makes the program wait until the Promise resolves.

How to fix Google Chrome running slow?

In this way, Chrome running slow should be fixed It is another feasible solution to clear your browsing data, as the cache and browsing history can lead to this issue as well. Step 1: Open Chrome Setting in the three-dots menu. Step 2: Navigate to Advanced -> Privacy and security -> Clear browsing data.

Is Google Chrome slower than Microsoft Edge?

I don't know what your are doing or how your machine is set up, but Chrome is not noticeably slower than Edge. Usually, I spend a chunk of my time on Quora countering the trolls and uninformed who are irrational Microsoft bashers, including questions like “Why us Edge so rubbish compared with Chrome”.

Do extensions slow down Google Chrome?

The answer to this is: “Absolutely!” Each extension you add will take more of the available memory and processing power afforded to Chrome. When you begin to have too many of them installed, it causes critical bloat, slowing down the browser. Does Norton slow down Google Chrome?

How to make Google Chrome run faster and more efficient?

To make your Chrome running smoothly and quickly, the first thing you should do is making sure it is updated to the latest version. After opening Chrome, you need to click the Three-dots button to expand Chrome menu. Then, choose Help from the menu and click About Google Chrome.


1 Answers

You can easily observe a difference between an await expression and lack thereof. At the very least, you are asking the engine to look at the microtask queue, possibly doing other work that happened as a result of I/O completing. Given that, this cannot possibly be optimized into nothing.

If you truly wish to spin the CPU for a few milliseconds, don't write await.

Here's an example. It prints 1 2 3.

Promise.resolve().then(()=>console.log(2));

(async()=>{
  console.log(1);
  await undefined;
  console.log(3);
})();

await undefined is not a "do-nothing" statement. It's JavaScript's cooperative multitasking.

like image 127
Josh Lee Avatar answered Sep 28 '22 16:09

Josh Lee