:JavaScript 中最快的循環(huán)是什么? 無論使用哪種編程語言,循環(huán)都是一種內(nèi)置功能。JavaScript 也不例外,它提供了多種實現(xiàn)循環(huán)的方法,偶爾會給開發(fā)人員帶來困惑:哪一種循環(huán)才是最快的?
以下是Javascript中可以實現(xiàn)循環(huán)的方法:
- For Loop
- While Loop
- Do-While Loop
- For-In Loop
- For-Of Loop
- ForEach Loop
- Map Loop
- Filter Loop
- Reduce Loop
- Some Loop
- Every Loop
- Find Loop
我們將對這些循環(huán)方法進行測試,以確定哪種方法最快。
為了比較每個循環(huán)的性能,我們將使用 console.time() 和 console.timeEnd() 方法來測量它們的執(zhí)行時間。
javascript代碼解讀復制代碼console.time('My Description'); // Code to measure console.timeEnd('My Description');
用于測試的任務(wù)是:將 5000 萬個項目從一個數(shù)組轉(zhuǎn)移到另一個數(shù)組。
javascript代碼解讀復制代碼console.time('Array Creation'); const numbersList = Array.from({ length: 50_000_000 }, () => Math.floor(Math.random() * 100)); console.timeEnd('Array Creation');
為確保公平比較,我們將異步運行每個循環(huán)。
雖然 For-In 的語法與 For-Of 類似,但它不是為數(shù)組設(shè)計的,因此不在測試之中。 For-In 更適合迭代具有多個屬性的對象,因為它迭代的是屬性名稱(或鍵)而不是值本身,而與數(shù)組一起使用會導致性能問題和意外行為。
scss代碼解讀復制代碼(async () => { await usingForLoop(numbersList); await usingWhile(numbersList); await usingDoWhile(numbersList); await usingForOf(numbersList); await usingForEach(numbersList); await usingMap(numbersList); await usingFilter(numbersList); await usingReduce(numbersList); await usingSome(numbersList); await usingEvery(numbersList); await usingFind(numbersList); })()
ForLoop
ini代碼解讀復制代碼const usingForLoop = async (array) => { console.time('FOR LOOP'); const newNumbersList = []; for (let i = 0; i < array.length; i++) { newNumbersList.push(array[i]); } console.timeEnd('FOR LOOP'); }
while
ini代碼解讀復制代碼const usingWhile = async (array) => { console.time('WHILE'); let i = 0; const newNumbersList = []; while (i < array.length) { newNumbersList.push(array[i]); i++; } console.timeEnd('WHILE'); }
doWhile
ini代碼解讀復制代碼const usingDoWhile = async (array) => { console.time('DO WHILE'); let i = 0; const newNumbersList = []; do { newNumbersList.push(array[i]); i++; } while (i < array.length); console.timeEnd('DO WHILE'); }
ForOf
javascript代碼解讀復制代碼const usingForOf = async (array) => { console.time('FOR OF'); const newNumbersList = []; for (const item of array) { newNumbersList.push(item); } console.timeEnd('FOR OF'); }
ForEach
javascript代碼解讀復制代碼const usingForEach = async (array) => { console.time('FOR EACH'); const newNumbersList = []; array.forEach((item) => newNumbersList.push(item)); console.timeEnd('FOR EACH'); }
Map
typescript代碼解讀復制代碼const usingMap = async (array) => { console.time('MAP'); const newNumbersList = array.map((number) => number); console.timeEnd('MAP'); }
Filer
javascript代碼解讀復制代碼const usingFilter = async (array) => { console.time('FILTER'); const newNumbersList = array.filter((item) => true); console.timeEnd('FILTER'); }
Reduce
javascript代碼解讀復制代碼const usingReduce = async (array) => { console.time('REDUCE'); const newNumbersList = array.reduce((acc, item) => { acc.push(item); return acc; }, []); console.timeEnd('REDUCE'); }
Some
javascript代碼解讀復制代碼const usingSome = async (array) => { console.time('SOME'); const newNumbersList = []; array.some((item) => { newNumbersList.push(item); return false; }); console.timeEnd('SOME') }
Every
javascript代碼解讀復制代碼const usingEvery = async (array) => { console.time('EVERY'); const newNumbersList = []; array.every((item) => { newNumbersList.push(item); return true; }); console.timeEnd('EVERY') }
Find
javascript代碼解讀復制代碼const usingFind = async (array) => { console.time('FIND'); const newNumbersList= []; array.find((item) => { newNumbersList.push(item); return false; }); console.timeEnd('FIND') }
任務(wù)運行了五次,顯示的測量值是計算得出的平均值。
測試平均結(jié)果如下:
從結(jié)果可以看出,前5名分別是:
- Map
- For Loop
- While
- Do While
- For Each
有趣的是只有Map是一個函數(shù)調(diào)用,其余的都是循環(huán)體。
另外該測試僅針對一項特定任務(wù)進行的,不同測試用例可能會有不同的結(jié)果,不同的內(nèi)存或者CPU也會有不一樣的表現(xiàn)。從本次測試的結(jié)果,我們可以看到Map 和 For Loop 的性能是最好的。令人失望的是For-Of,相對于For Loop,作為新出的一個API竟然效率這么拉跨。
Map每次循環(huán)都需要調(diào)用回調(diào)函數(shù),理論上不應(yīng)該比For Loop更快。但現(xiàn)代 JavaScript 引擎(如 V8)對高階函數(shù)(如 map、filter 等)進行了高度優(yōu)化,尤其是對數(shù)組的處理。引擎內(nèi)部可能會針對這些高階函數(shù)應(yīng)用特定的優(yōu)化策略,減少不必要的操作,進而提升性能。而且 map 是一個專門用于遍歷數(shù)組并返回新數(shù)組的高階函數(shù),V8 等引擎能夠更好地預(yù)測和優(yōu)化其內(nèi)部的操作路徑。而 for loop 是更通用的控制結(jié)構(gòu),可能沒有這些特定的優(yōu)化。
結(jié)論
從測試結(jié)果看Map和For Loop的循環(huán)效率相差不大,大家可以根據(jù)需要做選擇。map 無法中途退出,但可以返回一個新的數(shù)組。
?
該文章在 2024/11/29 10:26:58 編輯過