我注意到其他question循環中的性能差異,同時使用let
和var
變量聲明。Javascript臨時死區NodeJS 7.9.0性能下降?
初始問題是正確地回答的是,在使用let
for循環較慢因爲let
創建用於每次迭代保持let
聲明的變量的值的新範圍。要做更多的工作,所以慢一些是正常的。正如參考,我給的代碼和的NodeJS(7.9.0)的執行時間的結果:
請注意,以下關於版本的NodeJS所有的JavaScript代碼7.9.0
常規代碼:
'use strict';
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');
console.time('let');
for (let j = 0; j < 100000000; j++) {}
console.timeEnd('let');
輸出:
var: 55.792ms
let: 247.123ms
爲了避免在循環的每次迭代中額外聲明j
,我們在循環之前聲明j
變量。可以預料,現在這應該使let
循環性能匹配var
之一。 但是沒有!這是代碼,結果以供參考:循環之前定義
代碼let
:
'use strict';
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');
console.time('let');
let j;
for (j = 0; j < 100000000; j++) {}
console.timeEnd('let');
輸出:
var: 231.249ms
let: 233.485ms
我們可以看到,不僅let
循環沒有得到任何更快,但var
循環變得像let
一樣慢!唯一的解釋是,由於我們不在任何塊或函數中,因此這兩個變量都在全局模塊範圍內聲明。然而,如here所示,範圍中間的變量的let
聲明創建了時間死區,這使j
變量未初始化,而var
初始化如定義的變量。
所以雖然未初始化的變量沒有被引用的時間死區運行的代碼,必須相當慢....
最後以顯示尊重,我們聲明的程序頂部的j
變量顯示運行它的結果沒有暫時死區。
代碼不具有時間盲區:
'use strict';
let j;
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');
console.time('let');
for (j = 0; j < 100000000; j++) {}
console.timeEnd('let');
輸出:
var: 55.586ms
let: 55.009ms
現在無論let
和var
循環也有類似的性能優化!
有沒有人知道我對假死區性能的假設是否正確,或提供不同的解釋?
有趣的問題 - upvoted,你也應該在其他環境中嘗試。 –
我也很好奇那個,可能是關於內存分配的東西 –
這與TDZ絕對有關。請參閱[「性能」項目的要點](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified#tdz-is-everywhere-except-in-transpilers-and-engines)。這在我的腦海中是有道理的,但對我來說寫一個答案還不夠好。 –