JavaScript插入50万条数组记录时重复校验性能低下如何优化
性能问题原因及优化方案
原代码核心问题
- 功能bug:
Array.find()方法返回的是匹配到的第一个元素,未匹配到返回undefined,原代码判断existingObjects.length == 0逻辑完全错误,本身就无法正常实现去重效果 - 性能瓶颈:
Array.find()是线性查找,每次插入的时间复杂度为O(n),数据量到50万量级时总时间复杂度达到O(n²),必然会出现卡顿
优化方案
核心是新增一个哈希表(JS的Map或普通对象)存储唯一标识的映射,把查找复杂度从O(n)降到O(1),总复杂度降到O(n),完全适配50万条数据的场景:
- 全局额外维护一个
uniqueKeyMap,用来存储已插入记录的唯一键 - 把三个去重判断字段拼接成唯一键(用特殊分隔符避免字段内容冲突)
- 插入前先查
uniqueKeyMap中是否存在该键,不存在才执行插入操作,同时把键存入哈希表
优化后代码
// 全局新增哈希表,和AllDataArray同级维护 const uniqueKeyMap = new Map(); function AddDataToArray(StdName, currObjectSTD, bufferObject, attributes, bufferSTD) { // 生成唯一键,分隔符||可替换为三个字段中不会出现的任意字符 const uniqueKey = `${attributes.OBJECTID}||${bufferObject.name}||${StdName}`; // 哈希表查找,O(1)复杂度 if (uniqueKeyMap.has(uniqueKey)) { return false; } // 原代码中的objectID变量疑似为attributes.OBJECTID,这里修正为对应值 const objectID = attributes.OBJECTID; const currentObject = { "ID": 0, "currObjectSTD": currObjectSTD, "color": bufferObject.color, "name": bufferObject.name, "attributes": attributes, "StdName": StdName, "objectID": objectID, "bufferSTD": bufferSTD, "shape": null, "shapeSTD": null }; AllDataArray.push(currentObject); uniqueKeyMap.set(uniqueKey, true); return true; }
额外优化建议
- 如果不需要兼容ES6以下的环境,
Map的性能比普通对象更高,优先使用Map - 如果后续需要对数据做其他查询操作,也可以基于
Map做不同维度的索引,避免多次遍历数组
内容的提问来源于stack exchange,提问作者suhas
相关产品推荐
相关产品推荐

