在我的项目中进行JavaScript代码重构期间,我发现一些循环显着减慢。寻找根本原因我发现this SO question陈述减速是由for
循环和闭包创建中的let
声明造成的。 令我惊讶的移动let
和关闭了for
循环没有帮助,甚至使用var
代替let
for循环变量也于事无补,因为经济放缓是由let
引起的for
循环之后放置。 通过去除多余的细节我获得此代码段:Javascript var和v8和SpiderMonkey中的优化/放慢问题
"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;
\t \t console.timeEnd('let_in_loop'); //chrome: 137ms, FF:102ms
})();
(也JS Fiddle注意:在使用JS小提琴显示有点不同的结果,但类似的放缓仍然存在于同一个地方)
在Chrome运行这产生以下
without_let: 122ms
let_below: 411ms <----------- Slowdown for v8
let_above_and_in_loop: 153ms
let_in_loop: 137ms
一些谷歌搜索带我到the article,指出let
导致Chrome 56/V8 5.6之前的优化!但我的chrome是57.0.2987.133(64位)和v8版本5.7.492.71。 更多的惊喜试图在Firefox 52.0.2(32位)上运行。在这里,我们有另外一个地方,减速时let
创建的变量是内封闭使用:
without_let: 101.9ms
let_below: 99ms
let_above_and_in_loop: 899ms <----- Slowdown for SpiderMonkey
let_in_loop: 102ms
当我看到这个问题在一定程度上涉及到所谓的“时间死区”的功能,但仍不清楚:
为什么两个主流浏览器(主要JavaScript引擎)仍然无法优化片段的这些(不同)部分?
是否有任何变通办法继续使用
let
(除了使用巴贝尔转让进VAR)?假设我能够通过v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
UPD将选项传递到Chrome浏览器甚至直接V8: 在Chrome的版本58.0.3029.96,使镀铬后correspondng V8版本5.8.283.37(aconding到https://omahaproxy.appspot.com/) ://标志/#启用-V8-将来jmrk建议下面仍有放缓第三种情况(现2倍,而不是8倍)
without_let: 157.000ms
let_below: 155.000ms
let_above_and_in_loop: 304.000ms
let_in_loop: 201.000ms
火狐53.0(32位)
without_let: 278.650ms
let_below: 310.290ms
let_above_and_in_loop: 848.325ms
let_in_loop: 275.495ms
这不是他们*不能*,而是他们没有找到时间去实现它。您可能想要提交一些错误报告,以确定它们的优先顺序。 – Bergi
这里是v8报告https://bugs.chromium.org/p/v8/issues/detail?id=6188 这里是FF https://support.mozilla.org/zh-CN/questions/1158956 –
这里也是Bugzilla的项目https://bugzilla.mozilla.org/show_bug.cgi?id=1362930 –