一、代码问题
老代码(关键部分):
var findcomponentState = function (cid) {
let reval = new Array();
const info = ProjectInfo.componentStates.filter(item => cid == item.longId)
info.length > 0 ? reval.push(info[0]) : ''
return reval;
}
function updateComponentState(){
for(var i = 0; i < floors.length; ++i){
var obs = floors[i].children;
for (var j = 0; j < obs.length; ++j) {
var obj = obs[j];
var info = findcomponentState(obj.uuid);
}
}
}
1、循环floors数组
2、循环每个floors中元素的children数组
3、对children数组中的每个元素调用findcomponentState方法,在ProjectInfo.componentStates数组中找到对应元素,放于reval中,用于后续操作
前两步的时间复杂度为O(m * n)
第三步 findcomponentState 中的用filter进行查找操作 导致整个代码在数组数量大的情况下时间消耗非常大
测试测出其中第三步影响最大,所以对findcomponentState方法中的查找方法进行优化
二、优化(哈希查找)
1、将ProjectInfo.componentStates改为哈希表的数据结构进行存储
// 将对象数组转化为哈希表(以longId为键)
function toHash(arr){
const result = arr.reduce((map,obj)=>{
map[obj.longId] = obj
return map
},{})
return result
}
function getInfo(){
...
ProjectInfo.componentStatesHash = toHash(ProjectInfo.componentStates)
}
2、优化findcomponentState方法中的查找
var findcomponentState = function (cid) {
let reval = new Array();
ProjectInfo.componentStatesHash[cid] ? reval.push(ProjectInfo.componentStatesHash[cid]) : ''
return reval;
}
优化后的查找时间复杂度为O(1)
三、对比
老代码中使用数组方法filter方法进行查找,查阅后
filter()时间复杂度为 O(n)
具体来说,filter()方法需要遍历数组中的每一个元素,并对每个元素进行指定条件的判断。如果满足条件,就将该元素加入到结果数组中。因为需要遍历数组中的所有元素,并将满足条件的元素挑选出来,所以时间复杂度为 O(n)。
优化后的哈希查找 时间复杂度将为O(1)
测试后时间开销确实减少!