Javascript var vs let (de)optimization/slowdown issue in v8 and SpiderMonkey

早过忘川 提交于 2019-12-18 03:47:33

问题


During JavaScript code refactoring in my project I've found that some of my loops slowed down drastically. Searching for root cause I've found this SO question stating slowdown is caused by let statement inside for loop and closure creation. To my surprise moving let and closure out of the for loop didn't help, and even using var instead of let for loop variable also does not help because slowdown is caused by let placed after thefor loop. By removing extra details I've obtained this code snippet:

"use strict"
console.log("=========================");
(function(){
    var itr = 0;
    function f(){++itr;}
    console.time('without_let');
    for(var i = 0; i < 50000000; ++i){
        f();
    }
    var totals = 0;
    console.timeEnd('without_let'); //chrome: 122ms, FF:102ms
})();

(function(){
    var itr = 0;
    function f(){++itr;}
    console.time('let_below');
    for(var i = 0; i < 50000000; ++i){
        f();
    }
    let totals = 0; // <--- notice let instead of var
    console.timeEnd('let_below'); //chrome: 411ms, FF:99ms
})();

(function(){
    let itr = 0;
    function f(){++itr;}
    console.time('let_above_and_in_loop');
    for(let i = 0; i < 50000000; ++i){
        f();
    }
    var totals = 0;
    console.timeEnd('let_above_and_in_loop'); //chrome: 153ms, FF:899ms
})();

(function(){
    var itr = 0;
    function f(){++itr;}
    console.time('let_in_loop');
    for(let i = 0; i < 50000000; ++i){
        f();
    }
    var totals = 0;
		console.timeEnd('let_in_loop'); //chrome: 137ms, FF:102ms
})();

(also on JS Fiddle Note: using JS Fiddle shows little bit different results but similar slowdown is still present in the same places)

Running this on Chrome produces following

 without_let: 122ms
 let_below: 411ms <----------- Slowdown for v8
 let_above_and_in_loop: 153ms
 let_in_loop: 137ms

Some googling brought me to the article stating that let caused deoptimization prior to Chrome 56 / V8 5.6! but my chrome is 57.0.2987.133 (64-bit) and v8 ver 5.7.492.71. More surprises trying to run this on Firefox 52.0.2 (32-bit). Here we have slowdown in another place, when variable created with let is used inside closure:

 without_let: 101.9ms
 let_below: 99ms
 let_above_and_in_loop: 899ms <----- Slowdown for SpiderMonkey
 let_in_loop: 102ms

As I see the issue is somewhat related to so called "Temporal Dead Zone" feature, but still unclear:

  1. Why two major browsers (major JavaScript engines) still cannot optimize those (different) parts of the snippet?

  2. Are there any workarounds to keep using let (except using Babel to turn let into var)? Assume I'm able to pass options to Chrome or even directly to v8 via v8::V8::SetFlagsFromCommandLine(&argc, argv, true);

UPD: In Chrome ver 58.0.3029.96, correspondng v8 version 5.8.283.37 (aconding to https://omahaproxy.appspot.com/) after enabling chrome://flags/#enable-v8-future as jmrk suggested below there is still slowdown for third case (now 2 times instead of 8 times)

without_let: 157.000ms
let_below: 155.000ms
let_above_and_in_loop: 304.000ms
let_in_loop: 201.000ms

Firefox 53.0 (32bit)

without_let: 278.650ms
let_below: 310.290ms
let_above_and_in_loop: 848.325ms
let_in_loop: 275.495ms

回答1:


I can answer the V8 part of the question. The slowdown you're seeing is due to a limitation in the old optimizing compiler (known as "Crankshaft"). It hasn't been addressed in all this time because the team has been busy working on the new optimizing compiler ("Turbofan"), which is shipping in Chrome 59 (currently on the Canary and Dev channels, soon on Beta!).

In Chrome 58 (currently on Beta), you can already get a preview by setting the "Experimental JavaScript Compilation Pipeline" to "Enabled" (at chrome://flags/#enable-v8-future). Note that Chrome 59 will have a couple of additional performance improvements.

Side note: in an existing codebase, there isn't much benefit in migrating to let, so you could just keep using var.



来源:https://stackoverflow.com/questions/43153889/javascript-var-vs-let-deoptimization-slowdown-issue-in-v8-and-spidermonkey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!