Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How much is the performance overhead for awaiting an already fulfilled Promise?

While doing code reviews, I've recently come across such kind of code blocks:

const promises = [];
const data = [];
for (let piece of pieces) {
  for (let chunk of piece) {
    promises.push(execute(chunk)); //execute returns a promise which is not yet fulfilled
  }
  data = await Promise.all(promises);
}

Here pieces is an array of arrays. Note that due to certain constraints we cannot await all Promises at once, hence this sort of chunking.

In my feedback, I write that this appears to be an anti-pattern as we are also awaiting Promises which were resolved in the previous iterations and the following is the proper way of handling such scenarios:

const data = [];
for (let piece of pieces) {
  const promises = [];
  for (let chunk of piece) {
    promies.push(execute(chunk)); //execute returns a promise which is not yet fulfilled
  }
  data.push(... await Promise.all(promises));
}

At the end, data will be the same in both cases.

I understand how data is being populated in both cases. I would like to know how much is the performance overhead of awaiting an already fulfilled promise (which is happening in the first code block) and is it significant?

like image 592
sbmthakur Avatar asked Nov 24 '18 06:11

sbmthakur


People also ask

Does promise all increase performance?

Notice that it's not await that resolves them. Promise. all does not improve performance. It's the "not waiting for the first promise before starting the second task" that improves performance (if done correctly).

What is fulfilled promise?

: to do what one said one would definitely do.

How do you wait for promise to resolve?

The async keyword before a function declaration marks it as asynchronous, and within it we can use the await keyword to wait for a promise to resolve. To wait for our promise to resolve and get the resolution as a return value from it, we just use the await keyword in-front of the promise.

Is async await faster than promises?

Yes, you read that right. The V8 team made improvements that make async/await functions run faster than traditional promises in the JavaScript engine.


1 Answers

The overhead is minuscule - it needs to iterate the already fulfilled promise, inspect it, take out the data and put it inside the result array. Assuming native promises, I expect this to be optimised and not need a roundtrip to the event loop, if you had thenables in the array then all of them would need to get resolved to a promise and that promise would need to be awaited asynchronously, taking a toll on the promise job queue.

The overhead in processing time will not be significant compared to the actual asynchronous work done in your execute function.

However, no matter how small the overhead is, the issue with the first version of your code is that its runtime complexity is quadratic: Promise.all needs to iterate the whole promises array every time. The more chunks * pieces you have, the more pronounced the effect will be. I agree with your review feedback and would recommend the second version of the code.

like image 126
Bergi Avatar answered Nov 03 '22 00:11

Bergi