js查重去重性能优化心得
概述
今天产品反映有个5000条数据的页面的保存按钮很慢,查看代码看到是因为点击保存按钮之后,进行了查重操作,而查重操作是用2个for循环完成了,时间复杂度是O(n^2)。没办法,只能想办法优化一下了。
主要参考了这篇文章:JavaScript 高性能数组去重
源码
简单来说,这个页面的要求是查找一个数组中的重复项,并且返回重复项的行号。源码简化后如下:
checkData(tableData) {
// console.time('数组检查重复项时间');
// 检查重复项,检查空值(全局)
const repeatMidArr = [];
const repeatArr = [];
for (let i = 0; i < tableData.length; i += 1) {
// 检查重复项
for (let j = i + 1; j < tableData.length; j += 1) {
const arr1 = tableData[i].condition;
const arr2 = tableData[j].condition;
if (arr1.length === arr2.length && JSON.stringify(arr1) === JSON.stringify(arr2)) {
repeatMidArr.push(i + 1);
repeatMidArr.push(j + 1);
}
}
}
// 给repeatMidArr去重
repeatMidArr = repeatMidArr.sort();
if (repeatMidArr.length <= 1) {
repeatArr = repeatMidArr;
} else {
repeatArr.push(repeatMidArr[0]);
for (let i = 1; i < repeatMidArr.length; i += 1) {
if (repeatMidArr[i] !== repeatMidArr[i - 1]) repeatArr.push(repeatMidArr[i]);
}
}
// console.timeEnd('数组检查重复项时间');
if (repeatArr.length !== 0) {
this.sendRepeatMsg(repeatArr);
return true;
}
return false;
},
注意:
- 因为需要对一个数组查重,所以使用了JSON.stringify把数组转化为字符串简单处理。
- 给纯数字数组利用sort方法去重。
优化
优化的核心思想是算法中的hash表,也就是字典。在js中可以利用对象的键值不重复这个特性来把对象变成一个hash表。简化后的代码如下:
checkData(tableData) {
// console.time('数组检查重复项时间');
// 检查重复项,检查空值(全局)
const repeatObj = {};
let repeatMidArr = [];
let repeatArr = [];
for (let i = 0; i < tableData.length; i += 1) {
// 检查重复项(优化方法)
const itemCondition = JSON.stringify(tableData[i].condition);
const index = repeatObj[itemCondition];
if (!index) {
repeatObj[itemCondition] = i + 1;
} else {
repeatMidArr.push(index);
repeatMidArr.push(i + 1);
}
}
// 给repeatMidArr去重
repeatMidArr = repeatMidArr.sort();
if (repeatMidArr.length <= 1) {
repeatArr = repeatMidArr;
} else {
repeatArr.push(repeatMidArr[0]);
for (let i = 1; i < repeatMidArr.length; i += 1) {
if (repeatMidArr[i] !== repeatMidArr[i - 1]) repeatArr.push(repeatMidArr[i]);
}
}
// console.timeEnd('数组检查重复项时间');
if (repeatArr.length !== 0) {
this.sendRepeatMsg(repeatArr);
return true;
}
return false;
},
代码很简单,这里就不细说了。这种方法既然都能用到查重并返回重复项中,当然也能够用到去重里面去。
结果
优化之后,在5000条数据下,点击保存按钮的响应时间从35秒缩短到了3秒,性能提升了10倍!!!
js查重去重性能优化心得的更多相关文章
- angular性能优化心得
原文出处 脏数据检查 != 轮询检查更新 谈起angular的脏检查机制(dirty-checking), 常见的误解就是认为: ng是定时轮询去检查model是否变更.其实,ng只有在指定事件触发后 ...
- AngularJS性能优化心得,自己踩过的抗,及一些别人的经验(转哦)
脏数据检查 != 轮询检查更新 谈起angular的脏检查机制(dirty-checking), 常见的误解就是认为: ng是定时轮询去检查model是否变更.其实,ng只有在指定事件触发后,才进入$ ...
- JS日期格式化函数性能优化篇
最近开发的软件中需要用到日志功能,其中有一个重要功能是显示日期和时间.于是网上搜了一把,搜到大量的日期格式化函数,不过比较了下,感觉代码都不够优雅,而且性能都不给力.对线上一些代码进行了评测,以下是一 ...
- js怎么动态加载js文件(JavaScript性能优化篇)
下面介绍一种JS代码优化的一个小技巧,通过动态加载引入js外部文件来提高网页加载速度 [基本优化] 将所有需要的<script>标签都放在</body>之前,确保脚本执行之前完 ...
- [js高手之路]性能优化技巧 - 缓存与函数重载实战
所谓缓存,通俗点讲就是把已经做过的事情结果先暂时存起来,下次再做同样的事情,不用再重新去做,只要把之前的存的结果拿出来用即可,很明显大大提升了效率.他的应用场景非常广泛.如: 1.缓存ajax结果,大 ...
- springboot mybatis下临时表的创建和删除,可用于查重去重
/** * 创建临时表 */ @Update({"drop temporary table if exists ${tableName};", "create tempo ...
- C#中那些[举手之劳]的性能优化
隔了很久没写东西了,主要是最近比较忙,更主要的是最近比较懒...... 其实这篇很早就想写了 工作和生活中经常可以看到一些程序猿,写代码的时候只关注代码的逻辑性,而不考虑运行效率 其实这对大多数程序猿 ...
- C#程序员应该养成的程序性能优化写法
转载一个别人的文章 隔了很久没写东西了,主要是最近比较忙,更主要的是最近比较懒…… 其实这篇很早就想写了 工作和生活中经常可以看到一些程序猿,写代码的时候只关注代码的逻辑性,而不考虑运行效率 其实这对 ...
- babel-polyfill使用与性能优化
文章首发于笔者的个人博客 文章概览 本文主要内容包括:什么是babel-polyfill,如何使用,如何通过按需加载进行性能优化. 本文所有例子可以在 笔者的github 找到. 什么是babel-p ...
随机推荐
- ArrayList源码学习
1.ArrayList:基于数据实现,允许出现空值和重复元素,当ArrayList中添加的元素数量大于底层数组容量是,会通过扩容机制重新生成一个更大的数组.(非线程安全) 2.源码分析 构造函数 /* ...
- python输入一行字符,判断不同字符数量
输入一行字符,判断不同字符的数量, 分别用for循环和while循环完成 for循环 运用了字符串方法, isupper()判断是否为大写字母 islower()判断是否为小写字母 isdigit() ...
- 《ServerSuperIO Designer IDE使用教程》-4.增加台达PLC驱动及使用教程,从0到1的改变。发布:v4.2.3版本
v4.2.3 更新内容:1.优化数据存储部分,提高效率.2.修复数据库服务停止造成程序异常退出的现象.3.修复本机没有串口造成无法增加设备驱动的情况.4.增加编辑设备和监测点配置信息功能.5.增加台达 ...
- iOS 中文转拼音
- (NSString * ) chineseToPinyin:(NSString *) chinese{ CFStringRef hanzi = (__bridge CFStringRef)(chi ...
- JS数字转中文
function number2Chinese(n) { if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(n)) return '数据非法'; let unit = '京亿万仟佰 ...
- 个人总结ASP.NET必备面试题
1.你能解释下MVC的完整流程吗? 所有的终端用户请求被发送到控制器.控制器依赖请求去选择加载哪个模型,并把模型附加到对应的视图.附加了模型数据的最终视图做为响应发送给终端用户. 2. 那你说一下你对 ...
- look back to 2018
只写展望怎么行,还是缺一篇总结.2018年几乎没有怎么发朋友圈,需要一些文字记录一下这一年发生的事. 去年的现在,2018年的开端,结束了研一上学期充实的生活,下学期一项艰巨的任务就是完成大项目,一个 ...
- BZOJ2640 : 可见区域
设$base$表示直接能看到的面积,$f[i]$表示仅去掉线段$i$后新增的面积,$g[i][j]$表示仅去掉线段$i$和$j$后新增的面积. 删除一条线段的答案为$base+\max(f[i])$. ...
- mysql的复习
. 着重号,区分字段和关键字的符号 +号是运算的 起别名,其中的as可以省略 ifnull(expr1,expr2),expr1代表输入的字段,expr2代表如果输入的字段是null则为expr2 条 ...
- Java equals()方法和hashCode()方法
equals()方法 如果满足了以下任何一个条件,就不需要覆盖equals()方法: 1 类的每个实例本质上都是唯一的. 2 不关心类是否提供了“逻辑相等”的测试功能. 3 父类已经覆盖了equals ...