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 async
hronous
(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.