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倍!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM