傳統2個數組的嵌套查詢通常經過兩個循環體嵌套實現,時間複雜度爲:n^2;
而經過創建索引對象的形式的時間複雜度爲:n;這種犧牲內存來達到複雜度降冪的的方法能提升多少性能呢?
下面是以數組1長度爲10000;數組2爲50000的亂序數組進行測試的測試結果。(測試結果的單位都是ms)javascript
Firefox測試結果: 平均快48倍java
// 第一次 傳統的嵌套循環:1479 創建索引:30 // 第二次 傳統的嵌套循環:1852 創建索引:36 // 第三次 傳統的嵌套循環:1754 創建索引:38
Chrome測試結果: 平均快64倍算法
// 第一次 傳統的嵌套循環:1800 創建索引:26 // 第二次 傳統的嵌套循環:1297 創建索引:35 // 第三次 傳統的嵌套循環:2522 創建索引:27
IE11測試結果:平均快11倍數組
// 第一次 傳統的嵌套循環:110431 創建索引:616 // 第二次 傳統的嵌套循環:7172 創建索引:689 // 第三次 傳統的嵌套循環:7310 創建索引:686
完整的代碼(實際使用中請考慮數據類型校驗和是否爲空判斷)dom
// 情景:從數組arr1的id拿到數組arr2中的全部記錄,統計急了num的總和寫回到arr1中 // 模擬2個數組 var start = 1000000 // 定義模擬2個數組的方法;count: arr1的長度值;n: 爲arr2爲arr1的長度的多少倍 function getArr(count, n) { var o = { arr1: [], arr2: [] } for(var i = 0; i<count; i++){ o.arr1.push({id: start+i,count: 0}) for(var j = 0; j < n; j++){ o.arr2.push({ id: start + i, num: Math.round(Math.random()*1000) }) } } // 簡單的打亂數組 o.arr2.sort(function (a, b) { return a.num - b.num }) return o } // 傳統方法的嵌套循環 function setArrCount2(o) { var l1 = o.arr1.length var l2 = o.arr2.length var arr1 = o.arr1 var arr2 = o.arr2 for(var i = 0; i < l1; i++) { for(var j = 0; j < l2; j++) { if(arr1[i].id === arr2[j].id){ arr1[i].count += arr2[j].num } } } console.log(arr1) return arr1 } // 使用降冪算法 // arr2進行分組,創建以id值爲key的對象 function getArrGroup(arr, id) { var o = {} var len = arr.length var index for(var i = 0; i < len; i++){ index = arr[i][id] if(o[index]===undefined){ o[index] = [arr[i]] } else { o[index].push(arr[i]) } } return o } // 給arr1項的count賦值 function setArrCount(arr, o, fn) { var len = arr.length for(var i = 0; i < len; i++) { arr[i] = fn(arr, o, i) } console.log(arr) return arr } // 統計num的值 function getCount(arr) { var count = 0 var len = arr.length for(var i = 0; i < len; i++){ count += arr[i].num } return count } function someLogic(arr, o, i){ arr[i].count = getCount(o[arr[i].id]) return arr[i] } // 拿到2個數組 var myList = getArr(10000,5) var myList1 = getArr(10000,5) // 傳統方法 var st = new Date().getTime() setArrCount2(myList1) console.log(new Date().getTime() - st) // var startTime = new Date().getTime() var obj = getArrGroup(myList.arr2, 'id') setArrCount(myList.arr1, obj, someLogic) console.log(new Date().getTime() - startTime)
核心代碼:性能
// 使用降冪算法 // arr2進行分組,創建以id值爲key的對象 function getArrGroup(arr, id) { var o = {} var len = arr.length var index for(var i = 0; i < len; i++){ index = arr[i][id] // 創建索引,防止覆蓋 if(o[index]===undefined){ o[index] = [arr[i]] } else { o[index].push(arr[i]) } } return o } // 給arr1項的count賦值 function setArrCount(arr, o, id, fn) { var len = arr.length for(var i = 0; i < len; i++) { arr[i] = fn(arr, o, i)// fn定義處理邏輯 } console.log(arr) return arr }