传统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 }