JS 預分配陣列長度,到底是變慢還是變快?

2021-09-14 07:56:58 字數 1137 閱讀 4608

v8 的型別轉換只能通過格仔向下過渡。一旦將單精度浮點數新增到 smi 陣列中,即使稍後用 smi 覆蓋浮點數,它也會被標記為 double。類似地,一旦在陣列中建立了乙個洞,它將被永久標記為有洞 holey,即使稍後填充它也是如此。

一旦陣列被標記為有洞,它永遠是有洞的 - 即使它被打包了!從那時起,陣列上的任何操作都可能變慢。如果您計畫在陣列上執行大量操作,並且希望對這些操作進行優化,請避免在陣列中建立空洞。v8 可以更有效地處理密集陣列。

然後有人提出了乙個疑問:

為什麼先指定長度再初始化測試出來會快一點?

其實,兩者相比只是「可能」變慢。

具體因素有很多,比如預分配乙個很大的陣列,這時可以變快,lodash 的map函式就是這麼做的。因為初始化的時候分配完空間,就可以避免在陣列空間不夠用的時候反覆的記憶體申請和 gc 操作。而fast_elementsfast_holey_elements都不太慢,至少在所有元素中可以排到前二。

陣列分配完成後預設是fast_holey_smi_elements,當元素中新增了新的非 smi 值時,資料會進行型別轉換。--trace-elements-transitions的輸出:

elements transition [fast_holey_smi_elements -> fast_holey_elements]
我寫了乙個效能測試,對於 holey_elements,讀取的時候 holey 慢很多,寫入的時候效能一樣。如果陣列很大,預先分配大小後效能反而會提公升。

還有乙個重要的效能提示就是:避免讀數超出陣列的長度!這樣 v8 會在原型鏈上去找這個屬性。

js 多維陣列長度 js多維陣列

方法一 直接定義並且初始化,這種遇到數量少的情況可以用 var thearray 0 1 0 2 1 1 1 2 2 1 2 2 方法二 未知長度的二維陣列 var tarray new array 先宣告一維 for var k 0 k tarray k new array 宣告二維,每乙個一維陣...

js陣列長度獲取問題?

var test new array test test1 1 test test2 2 test 2 3 test length 輸出3 首先 test test1 1 和 test test2 2 都是屬性,可以通過test.test1 這樣來取值。但是 test 2 3 test.length...

js無法獲取陣列長度

通過console.log value instanceof array 去判斷,列印結果為true,但是在value.length獲取長度屬性時還是報錯。通過網上查資料解決了我的問題。出現問題原因 有的時候我們需要設定的key不是數字索引,而是非數字索引,那麼如何獲取長度呢。我們可以把array看...