在测试await
的性能时,我发现了一个令人困惑的谜团。我在控制台中多次运行了以下每个代码段,以过滤出Fluke,并获取了相关数据的平均时间。
(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);
结果:default: 5.322021484375ms
接下来,我尝试添加使其async
为讽刺
(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知道它的东西。开销非常低:default: 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倍:default: 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);
好吧,不是这样的:default: 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);
这将导致:default: 7.2041015625ms
好的,好的,让我们给Chrome带来疑问的好处。让我们假设一秒钟,他们的编程等待远远不够完美。
(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倍)?我正在寻找有关该问题的事实并进行客观分析,以解释我在上述性能测试中看到的令人困惑的谜团。
答案 0 :(得分:10)
您可以轻松地观察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的协作式多任务处理。