在测试await
的性能时,我发现了一个令人困惑的谜团。我在控制台中多次运行以下每个代码片段以过滤掉侥幸,并取相关数据的平均次数。
(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);
结果:默认:5.322021484375ms
接下来,我尝试添加使其成为 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);
不错! Chrome 知道它的东西。非常低的开销:默认值:8.712890625ms
接下来,我尝试添加 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);
这会导致速度降低 100 倍:默认值:724.706787109375ms
所以,一定有一些合乎逻辑的原因,对吧?我尝试比较之前的类型。
(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);
好的,不是这样:默认值:6.7939453125ms
那么,它一定是 promise 部分:检查传递给 await 的项目是否是一个 promise。那一定是罪魁祸首,我是对还是对?
(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);
这导致:默认值:7.2041015625ms
好吧,好吧,让我们相信 Chrome。让我们暂时假设,他们编写的 await 程序远不完美。
(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);
但即使这样也无法解释 await
的糟糕性能:default:7.85498046875ms
好吧,老实说,我放弃了。我认为 await
至少比现在快 100 倍。我想不出一个很好的理由来证明它在完美世界中不会快 100 倍。然而,我们并不生活在一个完美的世界中,因此存在一个问题:如何?如何?怎么这么慢有没有希望它在未来变得更快(比如说,大约快 100 倍)?我正在寻找事实和对此问题的客观分析,以解释我在上述性能测试中看到的令人费解的谜团。
最佳答案
您可以很容易地观察到 await
之间的差异表达和缺乏。至少,您要求引擎查看微任务队列,可能会执行因 I/O 完成而发生的其他工作。鉴于此,这不可能被优化成什么都没有。
如果你真的想让 CPU 旋转几毫秒,不要写 await
.
这是一个例子。它打印出 1 2 3
.
Promise.resolve().then(()=>console.log(2));
(async()=>{
console.log(1);
await undefined;
console.log(3);
})();
await undefined
不是“什么都不做”的声明。这是 JavaScript 的协作式多任务处理。
关于javascript - `await` 慢于 Chrome 中应有的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52221792/