1.數組循環遍歷方法
javascript傳統的數組遍歷有for循環,while循環,以及for-in。
本篇文章要比較的是以下幾種循環遍歷方法:
遍歷方式 | 備注 |
---|---|
正向for循環 | |
逆向for循環 | 減少一次控制條件比較,性能理論上比正向for循環稍好 |
while循環 | |
for-in循環 | 理論性能最差 |
for-each循環 | |
duff's device 循環 | 利用并發,理論性能最好wiki 介紹 |
2.代碼:
var number = 100000;//array大小
var iteranum = 100;//迭代次數
var array = [];
for(let i=0;i<number;i++)
{
array[i] = i+1;
}
//test cicle
var len = array.length;
//正常for循環
console.time('normal for');
for(let k=0;k<iteranum;k++)
{
for(let i=0;i<len;i++)
{
array[i]+1;
}
}
console.timeEnd('normal for');
//倒序for循環
console.time('reverse for');
for(let k=0;k<iteranum;k++)
{
for(let i=len-1;i--;)
{
array[i]+1;
}
}
console.timeEnd('reverse for');
//while循環
console.time('while');
for(let k=0;k<iteranum;k++)
{
let i=0;
while(i<len)
{
array[i]+1;
i++;
}
}
console.timeEnd('while');
//for-in循環
console.time('for-in');
for(let k=0;k<iteranum;k++)
{
for(let i in array)
{
array[i]+1;
}
}
console.timeEnd('for-in');
//for each 循環
console.time("for each");
for(let k=0;k<iteranum;k++)
{
array.forEach(function(e){
e+1;
});
}
console.timeEnd("for each");
//duff's device 循環
console.time("device's device");
for(let k=0;k<iteranum;k++)
{
let j = len % 8;
let templen = len-1;
while(j){
j--;
array[templen--]+1;
}
j = Math.floor(len / 8);
while(j){
j--;
array[templen--]+1;
array[templen--]+1;
array[templen--]+1;
array[templen--]+1;
array[templen--]+1;
array[templen--]+1;
array[templen--]+1;
array[templen--]+1;
}
}
console.timeEnd("device's device");
3.實驗步驟
- 實驗環境 ,操作系統 windows server 2016, node 8.0,cpu E5-1630 v3 @ 3.7GHz ,內存16G
- 數組內的數據操作很簡單,就是將每一個元素加1,但是不覆蓋原先的數據
- 實驗將采取多點采樣,數組樣本大小分別設置為:1000,10000,100000,1000000(1000次以下性能差距不大)
- 對每種方式分別進行100次仿真疊加,最后取100次的仿真結果平均數,作為該實驗數據的最終結果。
- 將結果以折線圖的形式展示
4.實驗結果
(1)結果表格(單位:微秒)
|遍歷方式/Item數量|1000|10000|100000|1000000|
|-|-|-|-|-|-|
|正向for循環|43|456|3840|35679|
|逆向for循環|37|378|3604|33488|
|while循環|66|296|2294|20576|
|for-in循環|87|958|32443|401017|
|for-each循環|64|395|4272|32435|
|duff's device 循環|20|235|2137|16364|
(2)結果折線圖
為了結果展示方便,將所有數據都進行了log轉換
幾種數組循環的性能對比
橫向為數組元素大小,縱向為運行時間(微秒)的log值。
上圖可見,duff's device方式執行效率一直很高,而for-in方式的效率一直很低,正向for和逆向for效率相差不大,逆向for稍微占優勢。
5.總結
- 總體來說for循環和for-each性能相當,在小數據量時也與while性能相當。for-in性能最差,duff's device性能最好。大數據量時,while性能優于for循環和for-each循環。
- 對于數據量不大的循環(<1000),不用考慮使用哪一種性能更好,可讀性是第一位
- 對于有較大數據量的循環和遍歷,如果性能不是瓶頸,那么普通的for循環(或者while,do-while,for-each)就可以了,畢竟可讀性強。
- 對于較大的數據量,如果array的循環操作已經成為瓶頸,或者性能非常重要,那么可以采用duff's device方案。
- 任何時候都不建議使用for-in,除非必須要用