关于前端性能优化有很多种方式,这里想谈谈算法中最常用的遍历的优化,其实以前我一直认为遍历效率的提升没有多大,但是看到实际数据后觉得这块的优化应该是实用性非常高的
下面通过一个例子来对比几者之间的差别
现有需求:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
1.for
var twoSum = function(nums, target) {
var temp;
for (let i = 0; i < nums.length; i++) {
for (let j = 0; j < nums.length; j++) {
if (nums[i] + nums[j] === target && i !== j) {
temp = [j, i];
}
}
}
return temp;
};
2.forEach
var twoSum = function(nums, target) {
var temp;
nums.forEach((num1, index1) => {
nums.forEach((num2, index2) => {
if (num1 + num2 === target && index1 !== index2) {
temp = [index2, index1];
}
})
});
return temp;
};
3.filter
var twoSum = function(nums, target) {
var temp;
for (let i = 0; i < nums.length; i++) {
let want = target - nums[i];
nums.filter((e, ii) => {
if (e === want && ii !== i) {
temp = [ii, i];
}
});
}
return temp;
};
在这里将want变量直接放入循环中从而减少一个块级作用域变量定义
var twoSum = function(nums, target) {
var temp;
for (let i = 0; i < nums.length; i++) {
nums.filter((e, ii) => {
if (e === target - nums[i] && ii !== i) {
temp = [ii, i];
}
});
}
return temp;
};
发现其执行时间有小幅度增加,而内存消耗并未减少
4.map
var twoSum = function(nums, target) {
var temp;
nums.map((num1, index1) => {
nums.map((num2, index2) => {
if (num1 + num2 === target && index1 !== index2) {
temp = [index2, index1];
}
})
});
return temp;
};
var twoSum = function(nums, target) {
var temp;
nums.forEach((num1, index1) => {
nums.map((num2, index2) => {
if (num1 + num2 === target && index1 !== index2) {
temp = [index2, index1];
}
})
});
return temp;
};
即使将其中一个循环替换为for或者forEach遍历,其实际影响也不大
对比几种遍历方式后发现几者的效率是 for > filter > forEach > map
由此得知
1.我们可以在其实际应用的情况下将map更换为filter,其也同样返回一个满足条件的数组对象,并且其性能与for循环接近
2.尽量减少遍历中数学方法计算的执行
ps:(如果页面中log过多的话,去除程序中多余的log对性能提升也有帮助)