java数组去重_js世界-数组去重到底最快的是谁?

昨天在写我司node中间层路由新方案的时候,在最后需要合并多个路由实例,在写到Router.merge函数的时候,突发奇想数组去重谁都会写,但效率哪个更高?于是就有了以下内容

常用数组去重

环境:mac 10.14.3 (18D109),node-8.6,8G内存,测试数据量15W

测试基础

const { log, c } = require('./util')

const origin = Array.from(new Array(100000), (x, index) => {
  return index
})

// 包含数据尽量均匀分布
const target = Array.from(new Array(50000), (x, index) => {
  return index + index
})

const start = Date.now()
log(`${c.cyan}start${c.end}`)

function merge2Array() {
  // 不同实现逻辑
}

log(`${c.cyan}after merge length${c.end}: ${merge2Array4(origin, target).length}`)

const end = Date.now()
log(`${c.red}all times${c.end}: ${end - start}`)

第一种

/**
 * 第一种,看似简洁,性能是不是也很牛逼?
 * filter + indexOf
 * @param {*} origin
 * @param {*} target
 */
function merge2Array(origin, target) {
  const result = origin.concat(target)
  return result.filter((item, index) => {
    return result.indexOf(item) === index
  })
}

4139656148353480438153967fbffd49.png

第二种

/**
 * 第二种,复杂点(是不是感觉有点像某种排序了?),代码这么多性能是不是很糟?
 * for + for
 * @param {*} origin
 * @param {*} target
 */
function merge2Array1(origin, target) {
  const result = origin.concat(target)
  let len = result.length
  for (let i = 0; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (result[i] === result[j]) {
        result.splice(j, 1);
        // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
        len--;
        j--;
      }
    }
  }
  return result
}

052b516d0f0866cb4e85f328c60404b5.png

第三种

/**
 * for + includes
 * @param {*} origin
 * @param {*} target
 */
function merge2Array2(origin, target) {
  origin = origin.concat(target)
  const result = []
  for (const i of origin) {
    !result.includes(i) && result.push(i)
  }
  return result
}

9f0179d11e4efb431e022a23f3243fdf.png

第四种

/**
 * sort + for
 * @param {*} origin
 * @param {*} target
 */
function merge2Array3(origin, target) {
  origin = origin.concat(target)
  origin.sort()
  const result = [origin[0]]
  const len = origin.length
  for (let i = 1; i < len; i++) {
    if (origin[i] !== origin[i-1]) {
      result.push(origin[i])
    }
  }
  return result
}

eec6e2ae9b6738c2ee5b38084f5fb61a.png

第五种

/**
 * Array.from + Set
 * 代码最少,性能最好?
 * @param {*} origin
 * @param {*} target
 */
function merge2Array4 (origin, target) {
  return Array.from(new Set([...origin, ...target]))
}

550b2409e249273fe8d4cb83a0141995.png

第六种

/**
 * for + obj-keys
 * 单一基础类型最快的
 * @param {*} origin
 * @param {*} target
 */
function merge2Array5(origin, target) {
  origin = origin.concat(target)
  const result = []
  const tagObj = {}
  for (const i of origin) {
    if (!tagObj[i]) {
      result.push(i)
      tagObj[i] = 1
    }
  }
  return result
}

0bb391631cc7b0035beaa0c287f7fba2.png

第七种

/**
 * for + set
 * 多种基础数据类型最快
 * @param {*} origin
 * @param {*} target
 */
function merge2Array6(origin, target) {
  origin = origin.concat(target)
  const result = []
  const set = new Set()
  for (const i of origin) {
    if (!set.has(i)) {
      result.push(i)
      set.add(i)
    }
  }
  return result
}

a7ab2bc3c151ff7cacc18411fd3ad361.png

数据级上升(150W)

我们针对最后两种方法进行数量级提升,提升至150w数据

Array.from + Set

75966e9e523c7be90267f595ac7c7eed.png

for + obj-keys

d1b059a9f20dfb3baa444ed2399ef910.png

for + set

9b60d75843f141372aff76a2ababf4a8.png

总结

  • 如果你去重的是单一基础类型,那直接用for-obj-keys方式是最快的
  • 如果你去重的是多种基础类型,最快的是for-set方式是最快的
schacker/merge2Array​github.com
400d835c192b96ea91f0715433406640.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值