為什么普通 for 循環(huán)的性能遠(yuǎn)遠(yuǎn)高于 forEach 的性能?

作為一名前端開(kāi)發(fā),for和foreach循環(huán)遍歷幾乎每天都在使用,那么這兩種遍歷方式哪一種效率更高呢? 效率高的原因是什么呢?

一、for( )循環(huán)

通過(guò)下標(biāo),對(duì)循環(huán)中的代碼反復(fù)執(zhí)行,功能強(qiáng)大,可以通過(guò)index取得元素。在處理比較復(fù)雜的處理的時(shí)候較為方便

二、forEach( )循環(huán)

forEach() 方法用于調(diào)用數(shù)組的每個(gè)元素,并將元素傳遞給回調(diào)函數(shù)。foreach有的也叫增強(qiáng)for循環(huán),foreach其實(shí)是for循環(huán)的一個(gè)特殊簡(jiǎn)化版。注意,forEach() 對(duì)于空數(shù)組是不會(huì)執(zhí)行回調(diào)函數(shù)的

array.forEach(function(currentValue, index, arr), thisValue)

function(currentValue, index, arr):必需。 數(shù)組中每個(gè)元素需要調(diào)用的函數(shù)。

| currentValue | 必需,當(dāng)前元素 |
| index | 可選,當(dāng)前元素的索引值。 |
| arr | 可選,當(dāng)前元素所屬的數(shù)組對(duì)象。 |

thisValue:可選。傳遞給函數(shù)的值一般用 "this" 值。如果這個(gè)參數(shù)為空, "undefined" 會(huì)傳遞給 "this"

三、console.time和console.timeEnd用法

console.time和console.timeEnd這兩個(gè)方法可以用來(lái)讓W(xué)EB開(kāi)發(fā)人員測(cè)量一個(gè)javascript腳本程序執(zhí)行消耗的時(shí)間。隨著WEB應(yīng)用越來(lái)越重要,JavaScript的執(zhí)行性能也日益受到重視,WEB開(kāi)發(fā)人員知道一些性能測(cè)試機(jī)器是必須的。測(cè)試JavaScript性能的方法有很多,但console.time/console.timeEnd兩個(gè)方法是最基本、最直接的技巧。

  1. console.time方法是開(kāi)始計(jì)算時(shí)間
  2. console.timeEnd是停止計(jì)時(shí),輸出腳本執(zhí)行的時(shí)間。
  3. 這兩個(gè)方法中都可以傳入一個(gè)參數(shù),作為計(jì)時(shí)器的名稱(chēng),它的作用是在代碼并行運(yùn)行時(shí)分清楚各個(gè)計(jì)時(shí)器。
  4. 對(duì)console.timeEnd的調(diào)用會(huì)立即輸出執(zhí)行總共消耗的時(shí)間,單位是毫秒。
// 啟動(dòng)計(jì)時(shí)器
console.time('計(jì)時(shí)器名稱(chēng)');

// (寫(xiě)一些測(cè)試用代碼)

// 停止計(jì)時(shí),輸出時(shí)間
console.timeEnd('計(jì)時(shí)器名稱(chēng)');

四、測(cè)試性能

在1000000這個(gè)級(jí)別下,forEach 的性能高于for

let arrs = new Array(1000000);

console.time('for');
for (let i = 0; i < arrs.length; i++) {};
console.timeEnd('for'); // for: 10.329833984375ms

console.time('forEach');
arrs.forEach((arr) => {});
console.timeEnd('forEach'); // forEach: 5.076904296875ms

在10000000這個(gè)級(jí)別下,forEach 的性能還是高于for

let arrs = new Array(10000000);

console.time('for');
for (let i = 0; i < arrs.length; i++) {};
console.timeEnd('for'); // for: 95.157958984375ms

console.time('forEach');
arrs.forEach((arr) => {});
console.timeEnd('forEach'); // forEach: 37.9619140625ms

在100000000級(jí)以上的量級(jí)上 ,forEach的性能遠(yuǎn)遠(yuǎn)低于for的性能

let arrs = new Array(100000000);

console.time('for');
for (let i = 0; i < arrs.length; i++) {};
console.timeEnd('for'); // for: 939.18994140625ms

console.time('forEach');
arrs.forEach((arr) => {});
console.timeEnd('forEach'); // forEach: 1614.8642578125ms

五、for和forEach的區(qū)別

【3.1】遍歷

for循環(huán)按順序遍歷,forEach使用iterator迭代器遍歷

【3.2】數(shù)據(jù)結(jié)構(gòu)

for循環(huán)是隨機(jī)訪問(wèn)元素,foreach是順序鏈表訪問(wèn)元素

【3.3】性能上

對(duì)于arraylist,是順序表,使用for循環(huán)可以順序訪問(wèn),速度較快;使用foreach會(huì)比f(wàn)or循環(huán)稍慢一些。
對(duì)于linkedlist,是單鏈表,使用for循環(huán)每次都要從第一個(gè)元素讀取next域來(lái)讀取,速度非常慢;使用foreach可以直接讀取當(dāng)前結(jié)點(diǎn),數(shù)據(jù)較快;

六、如何選擇

foreach相對(duì)于for循環(huán),代碼減少了,但是foreach依賴(lài)IEnumerable。在運(yùn)行的時(shí)候效率低于for循環(huán)。當(dāng)然了,在處理不確定循環(huán)次數(shù)的循環(huán),或者循環(huán)次數(shù)需要計(jì)算的情況下。使用foreach比較方便。而且foreach的代碼經(jīng)過(guò)編譯系統(tǒng)的代碼優(yōu)化后,和for循環(huán)的循環(huán)類(lèi)似。

可以說(shuō),foreach語(yǔ)句是for語(yǔ)句的特殊簡(jiǎn)化版本,在遍歷數(shù)組、集合方面,foreach為開(kāi)發(fā)人員提供了極大的方便。在復(fù)雜的循環(huán)設(shè)計(jì)時(shí),還是應(yīng)該使用for循環(huán)更加的靈活。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容