• 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;
        },
    

    注意:

    1. 因为需要对一个数组查重,所以使用了JSON.stringify把数组转化为字符串简单处理。
    2. 给纯数字数组利用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倍!!!

  • 相关阅读:
    并发编程 之 生产者消费者模型
    并发编程 之 IPC机制
    Django + DRF + Elasticsearch 实现搜索功能
    时间上相邻query,前缀去重
    列表套字典,将字典元素去重
    K8s
    docker
    数据处理
    Django日志配配置
    Canvas 获取颜色值
  • 原文地址:https://www.cnblogs.com/yangzhou33/p/10485805.html
Copyright © 2020-2023  润新知