gpt4 book ai didi

javascript - 为什么在 Chrome 上在 `let` 循环中使用 `for` 这么慢?

转载 作者:行者123 更新时间:2023-12-03 02:27:27 25 4
gpt4 key购买 nike

重大更新。

尚未考虑 Chrome 主要版本新的 Ignition+Turbofan engines Chrome Canary 59 已经解决了这个问题。测试显示 letvar 声明的循环变量的时间相同。

<小时/>

原始(现在没有实际意义)问题。

当在 Chrome 上的 for 循环中使用 let 时,与将变量移出循环范围相比,它的运行速度非常慢。

for(let i = 0; i < 1e6; i ++); 

需要两倍的时间

{ let i; for(i = 0; i < 1e6; i ++);}

这是怎么回事?

代码片段展示了其中的差异,并且仅影响 Chrome,并且从我记事起 Chrome 支持 let 就一直如此。

var times = [0,0]; // hold total times
var count = 0; // number of tests

function test(){
var start = performance.now();
for(let i = 0; i < 1e6; i += 1){};
times[0] += performance.now()-start;
setTimeout(test1,10)
}
function test1(){
// this function is twice as quick as test on chrome
var start = performance.now();
{let i ; for(i = 0; i < 1e6; i += 1);}
times[1] += performance.now()-start;
setTimeout(test2,10)
}

// display results
function test2(){
var tot =times[0]+times[1];
time.textContent = tot.toFixed(3) + "ms";
time1.textContent = ((times[0]/tot)*100).toFixed(2) + "% " + times[0].toFixed(3) + "ms";
time2.textContent = ((times[1]/tot)*100).toFixed(2) + "% " + times[1].toFixed(3) + "ms";
if(count++ < 1000){;
setTimeout(test,10);
}
}
var div = document.createElement("div");
var div1 = document.createElement("div");
var div2 = document.createElement("div");
var time = document.createElement("span");
var time1 = document.createElement("span");
var time2 = document.createElement("span");
div.textContent = "Total execution time : "
div1.textContent = "Test 1 : "
div2.textContent = "Test 2 : "
div.appendChild(time);
div1.appendChild(time1);
div2.appendChild(time2);
document.body.appendChild(div);
document.body.appendChild(div1);
document.body.appendChild(div2);
test2()

当我第一次遇到这个问题时,我以为这是因为新创建的 i 实例,但以下显示事实并非如此。

请参阅代码片段,因为我已经消除了使用 ini 随机优化附加 let 声明然后添加到不确定的 k 值的任何可能性。

我还添加了第二个循环计数器p

var times = [0,0]; // hold total times
var count = 0; // number of tests
var soak = 0; // to stop optimizations
function test(){
var j;
var k = time[1];
var start = performance.now();
for(let p =0, i = 0; i+p < 1e3; p++,i ++){j=Math.random(); j += i; k += j;};
times[0] += performance.now()-start;
soak += k;
setTimeout(test1,10)
}
function test1(){
// this function is twice as quick as test on chrome
var k = time[1];
var start = performance.now();
{let p,i ; for(p = 0,i = 0; i+p < 1e3; p++, i ++){let j = Math.random(); j += i; k += j}}
times[1] += performance.now()-start;
soak += k;
setTimeout(test2,10)
}

// display results
function test2(){
var tot =times[0]+times[1];
time.textContent = tot.toFixed(3) + "ms";
time1.textContent = ((times[0]/tot)*100).toFixed(2) + "% " + times[0].toFixed(3) + "ms";
time2.textContent = ((times[1]/tot)*100).toFixed(2) + "% " + times[1].toFixed(3) + "ms";
if(count++ < 1000){;
setTimeout(test,10);
}
}
var div = document.createElement("div");
var div1 = document.createElement("div");
var div2 = document.createElement("div");
var time = document.createElement("span");
var time1 = document.createElement("span");
var time2 = document.createElement("span");
div.textContent = "Total execution time : "
div1.textContent = "Test 1 : "
div2.textContent = "Test 2 : "
div.appendChild(time);
div1.appendChild(time1);
div2.appendChild(time2);
document.body.appendChild(div);
document.body.appendChild(div1);
document.body.appendChild(div2);
test2()

最佳答案

更新:2018 年 6 月:Chrome 现在的优化效果比首次发布此问题和答案时要好得多;如果您不在循环中创建函数,那么在 for 中使用 let 不再有任何明显的惩罚(如果您这样做,则好处是值得的)。

<小时/>

因为循环的每次迭代都会创建一个新的 i,因此在循环内创建的闭包将覆盖该迭代的 i evaluation of a for loop body 的算法规范涵盖了这一点。 ,它描述了每次循环迭代创建一个新的变量环境。

示例:

for (let i = 0; i < 5; ++i) {
setTimeout(function() {
console.log("i = " + i);
}, i * 50);
}

// vs.
setTimeout(function() {
let j;
for (j = 0; j < 5; ++j) {
setTimeout(function() {
console.log("j = " + j);
}, j * 50);
}
}, 400);

还有更多工作要做。 如果每个循环不需要一个新的 i,请在循环外使用 let 请参阅上面的更新,无需除了边缘情况之外,避免使用其他情况。

我们可以预期,既然除了模块之外的所有内容都已实现,V8 可能会改进新内容的优化,但毫不奇怪,功能最初应该优先于优化。

很高兴其他引擎已经完成了优化,但 V8 团队显然还没有做到这一点。请参阅上面的更新。

关于javascript - 为什么在 Chrome 上在 `let` 循环中使用 `for` 这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40449494/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com