本文鏈接:https://blog.csdn.net/longzhoufeng/article/details/79815550
今天要說的是最簡單的 for 循環,一個簡單的 for 循環看似沒有任何優化的意義,但實質上優化前后差距挺大的,那么該如何優化呢?
從最簡單的遍歷數組說起。
// 定義一個數組arr(假設是從后台返回的數據) let i = 0; let arr = []; while (i < 50) { arr.push(i); i++; }
如果我們想從數組 arr 中取出數據,就必須要進行遍歷,普遍的做法是:
for (let i = 0; i < arr.length; i++) { // arr[i] }
但其實這樣的寫法遍歷是最慢的,他要經過兩次迭代,第一次是 i 的迭代,每次都要判斷 i 是否小於 arr.length,第二次是 arr 的迭代,每次循環 arr 都會調用底層的迭代器,對長度進行計算,這樣循環的效率非常低,時間空間復雜度為 O[n^2]。
下面進行優化,看看兩者到底有什么區別:
for (let i = 0, len = arr.length; i < len; i++) { // arr[i] }
區別就是,整個循環當中,我們預存了 len 來保存數組的長度,這樣不需要每次循環都調用底層迭代器,調用一次即可,這樣的時間空間復雜度為 O[n+1]。
但是這並不是最完美的,因為會多了一次迭代操作,那么該如何進行優化呢?
以下進行進一步優化:
注意:使用該種方法,每次在循環體內部取到的 i 是 ++ 后的值,所以在使用索引的時候需要 -1.
for (let i = 0, item; item = arr[i++];) { // item }
這次迭代的時間空間復雜度為 O[n] ,完美做到了每次一迭代沒有通過長度進行判斷,而是直接通過下標進行取值的方式映射到了循環體內部。
最后用5萬條數據進行測試三種方式的循環時間:
let index = 0; let arr = []; while (index < 50) { arr.push(index); index++; } console.time('one'); for (let i = 0; i < arr.length; i++) { // arr[i] } console.timeEnd('one'); // one: 2.09765625ms console.time('two'); for (let i = 0, len = arr.length; i < len; i++) { // arr[i] } console.timeEnd('two'); // two: 0.839111328125ms console.time('three'); for (let i = 0, item; item = arr[i++];) { // arr[i] } console.timeEnd('three'); console.time('four'); arr.map(item=>{ //iitem }); console.timeEnd('four');
50000數據測試結果: VM616:12 one: 1.84912109375ms VM616:19 two: 1.364013671875ms VM616:26 three: 0.012939453125ms VM616:31 four: 2.016845703125ms
50數據測試結果:
VM669:5 one: 0.00927734375ms
VM669:12 two: 0.005126953125ms
VM669:19 three: 0.0048828125ms
VM669:24 four: 0.039306640625ms
可以看出,無論數據多少,第三種寫法都存在一定優勢.
可以看出,傳統的寫法需要 2ms 才能進行迭代完成,優化后只需 0.8ms ,最終優化的結果只需要 0.004ms 就能迭代完成,性能大大提升,在數據量大的情況下,效果顯而易見。
另外一種優化策略是“達夫設備”,但是隨着市面上瀏覽器性能的逐漸增強,老版本的瀏覽器運用達夫設備優化性能能得到大幅度的提升,而新版的瀏覽器引擎肯定對循環迭代語句進行了更強的優化,所以達夫設備能實現的優化效果日趨減弱甚至於沒有。而在查閱資料的過程中,有人提出 while 循環的效果和達夫設備不相上下,所以這里就不做介紹了。
---------------------
版權聲明:本文為CSDN博主「longzhoufeng」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/longzhoufeng/article/details/79815550