const、let和var对v8javascript性能的影响?

const、let和var对v8javascript性能的影响?,javascript,performance,constants,v8,let,Javascript,Performance,Constants,V8,Let,无论功能差异如何,使用新关键字“let”和“const”是否会对相对于“var”的性能产生普遍或特定的影响 运行程序后: function timeit(f, N, S) { var start, timeTaken; var stats = {min: 1e50, max: 0, N: 0, sum: 0, sqsum: 0}; var i; for (i = 0; i < S; ++i) { start = Date.now();

无论功能差异如何,使用新关键字“let”和“const”是否会对相对于“var”的性能产生普遍或特定的影响

运行程序后:

function timeit(f, N, S) {
    var start, timeTaken;
    var stats = {min: 1e50, max: 0, N: 0, sum: 0, sqsum: 0};
    var i;
    for (i = 0; i < S; ++i) {
        start = Date.now();
        f(N);
        timeTaken = Date.now() - start;

        stats.min = Math.min(timeTaken, stats.min);
        stats.max = Math.max(timeTaken, stats.max);
        stats.sum += timeTaken;
        stats.sqsum += timeTaken * timeTaken;
        stats.N++
    }

    var mean = stats.sum / stats.N;
    var sqmean = stats.sqsum / stats.N;

    return {min: stats.min, max: stats.max, mean: mean, spread: Math.sqrt(sqmean - mean * mean)};
}

var variable1 = 10;
var variable2 = 10;
var variable3 = 10;
var variable4 = 10;
var variable5 = 10;
var variable6 = 10;
var variable7 = 10;
var variable8 = 10;
var variable9 = 10;
var variable10 = 10;

function varAccess(N) {
    var i, sum;
    for (i = 0; i < N; ++i) {
        sum += variable1;
        sum += variable2;
        sum += variable3;
        sum += variable4;
        sum += variable5;
        sum += variable6;
        sum += variable7;
        sum += variable8;
        sum += variable9;
        sum += variable10;
    }
    return sum;
}

const constant1 = 10;
const constant2 = 10;
const constant3 = 10;
const constant4 = 10;
const constant5 = 10;
const constant6 = 10;
const constant7 = 10;
const constant8 = 10;
const constant9 = 10;
const constant10 = 10;

function constAccess(N) {
    var i, sum;
    for (i = 0; i < N; ++i) {
        sum += constant1;
        sum += constant2;
        sum += constant3;
        sum += constant4;
        sum += constant5;
        sum += constant6;
        sum += constant7;
        sum += constant8;
        sum += constant9;
        sum += constant10;
    }
    return sum;
}


function control(N) {
    var i, sum;
    for (i = 0; i < N; ++i) {
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
    }
    return sum;
}

console.log("ctl = " + JSON.stringify(timeit(control, 10000000, 50)));
console.log("con = " + JSON.stringify(timeit(constAccess, 10000000, 50)));
console.log("var = " + JSON.stringify(timeit(varAccess, 10000000, 50)));
然而,此处所述的讨论似乎表明了在某些情况下性能差异的真正潜力:

TL;DR 理论上,该循环的未优化版本:

for (let i = 0; i < 500; ++i) {
    doSomethingWith(i);
}
因为使用
let
为每个循环迭代创建了一个不同的
i
变量,而使用
var
只有一个
i

反驳的事实是
var
被提升,因此它在循环外声明,而
let
仅在循环内声明,这可能提供优化优势

在实践中,在2018年,现代JavaScript引擎对循环进行了足够的内省,以了解何时可以优化这种差异。(即使在那之前,您的循环很可能做了足够的工作,因此额外的
let
相关开销也被冲掉了。但现在您甚至不必担心它。)

注意合成基准测试,因为它们极易出错,并以实际代码所不能的方式触发JavaScript引擎优化器(好的和坏的方式)。但是,如果您想要一个合成基准,这里有一个:

const now=typeof performance==“object”&&performance.now
? performance.now.bind(性能)
:Date.now.bind(日期);
const btn=document.getElementById(“btn”);
btn.addEventListener(“单击”,函数(){
btn.disabled=true;
runTest();
});
常数maxTests=100;
const loopLimit=50000000;
const expectedX=124999795000000;
函数运行测试(索引=1,结果={usingVar:0,usingLet:0}){
log(${maxTests}``的`Running Test#${index});
设置超时(()=>{
const varTime=usingVar();
const letTime=usingLet();
results.usingVar+=varTime;
results.usingLet+=letTime;
log(`Test${index}:var=${varTime}ms,let=${letTime}ms`);
++指数;
if(索引运行测试(索引,结果),0);
}否则{
log(`Average time with var:${(results.usingVar/maxTests).toFixed(2)}ms`);
log(`Average time with let:${(results.usingLet/maxTests.toFixed(2)}ms`);
btn.disabled=false;
}
}, 0);
}
使用var()的函数{
const start=now();
设x=0;
对于(变量i=0;i
T.J.克劳德的答案太棒了。

这里有一个补充:“什么时候我可以在编辑现有的var声明到const时获得最大的回报?”

我发现最大的性能提升与“导出”函数有关

因此,如果文件A、B、R和Z正在调用文件U中通过应用程序常用的“实用程序”函数,那么将该实用程序函数切换到“const”和父文件对const的引用可以提高性能。在我看来,它的速度并没有明显加快,但对于我的整体式弗兰肯斯坦ed应用程序来说,总体内存消耗减少了约1-3%。如果你在云端或裸机服务器上花费了大量现金,这可能是花30分钟梳理并更新一些var声明到const的一个很好的理由

我意识到,如果你读到const、var和let如何在封面下工作,你可能已经得出了上述结论。。。但万一你“瞥”了一眼:D

根据我在进行更新时对节点v8.12.0的基准测试的记忆,我的应用程序从~240MB RAM的空闲消耗变为~233MB RAM。

“LET”在循环声明中更好。

在navigator中进行简单测试(5次),如下所示:

// WITH VAR
console.time("var-time")
for(var i = 0; i < 500000; i++){}
console.timeEnd("var-time")
//使用VAR
控制台时间(“变量时间”)
对于(var i=0;i<500000;i++){}
console.timeEnd(“变量时间”)
平均执行时间超过2.5ms

// WITH LET
console.time("let-time")
for(let i = 0; i < 500000; i++){}
console.timeEnd("let-time")
//带LET
时间(“让时间来吧”)
对于(设i=0;i<500000;i++){}
console.timeEnd(“等待时间”)
平均执行时间超过1.5ms


我发现使用let的循环时间更好

T.J.Crowder的答案很好,但:

  • “let”是为了使代码更可读,而不是更强大
  • 从理论上讲,let将比var慢
  • 根据实践,编译器不能完全解决(静态分析)一个未完成的程序,因此有时会错过优化
  • 在任何情况下,使用“let”都需要更多的CPU进行内省,必须在google v8开始解析时启动测试台
  • 如果内省失败,“let”将对V8垃圾收集器施加压力,它将需要更多的迭代来释放/重用。它还将消耗更多的内存。法官必须考虑到这些要点
  • 谷歌的关闭将改变让在变
  • var和let之间的性能差距的影响可以在实际的完整程序中看到,而不是在单个基本循环中看到


    无论如何,在不需要的地方使用let会降低代码的可读性。

    我认为这取决于用法,例如,在块作用域中使用的
    let
    应该比
    var
    性能更好,后者没有块作用域,只有函数作用域。如果我可以问,为什么是@adeneo?@sean2078-如果您需要声明一个只存在于块作用域中的变量,
    let
    会这样做,然后是ga
    // WITH VAR
    console.time("var-time")
    for(var i = 0; i < 500000; i++){}
    console.timeEnd("var-time")
    
    // WITH LET
    console.time("let-time")
    for(let i = 0; i < 500000; i++){}
    console.timeEnd("let-time")