IndexOf、Map.has、includes性能对比

3,537 阅读1分钟

前情提要:

有道题:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。

结题思路上是在循环这个数组的时候用给定的target减去当前循环项,看看当前数组里有没有这个循环项,答案中使用的是Map.has方法来判断有没有,我使用的是indexOf来判断。

因为我知道indexOf底层也是通过循环来判断,但是不知道Map.has底层逻辑是什么,也不知道这两个对性能有什么影响。这里做一次测试。

测试过程

  1. 先随机创建一个数组
// 生成随机数
function getRandom(num) {
    let randomArr = [];
    for (let i = 0; i < num; i++) {
        randomArr.push(Math.ceil(Math.random()*10));
    }
    return randomArr;
}
  1. 循环数组进行处理判断
const _sumNum = 18;
function getIndex() {
    const _randomArr = getRandom(10000);
    let _resultArr = [];
    console.time('getIndex');
    // 使用indexof方法
    for (let i = 0; i < _randomArr.length; i++) {
        const _randomItem = _randomArr[i];
        if (_randomArr.indexOf(_sumNum - _randomItem) > -1) {
            _resultArr.push(_randomItem, _sumNum - _randomItem);
        }
    }
    console.time('getIndex');
    // 使用includes方法
    for (let i = 0; i < _randomArr.length; i++) {
        const _randomItem = _randomArr[i];
        if (_randomArr.includes(_sumNum - _randomItem)) {
            _resultArr.push(_randomItem, _sumNum - _randomItem);
        }
    }
    // 使用Map处理
    // console.time('getIndex');
    // const _randomMap = new Map();
    // for (let i = 0; i < _randomArr.length; i++) {
    //     const _randomItem = _randomArr[i];
    //     _randomMap.set(_randomItem, 1);
    // }
    // for (let i = 0; i < _randomArr.length; i++) {
    //     const _randomItem = _randomArr[i];
    //     if (_randomMap.has(_sumNum - _randomItem)) {
    //         _resultArr.push(_randomItem, _sumNum - _randomItem);
    //     }
    // }
    console.timeEnd('getIndex');
}

结果:(每个结果都是取10次的平均值)

循环个数indexOf方式(单位ms)Map方式(单位ms)includes(单位ms)
1000.028030.028130.02951
5000.209550.076140.22783
10000.832920.148110.74549
500017.76150.6763917.6322
1000066.68593.359569.3237

次数展示

  • indexOf方式
    • 100::
      • 0.0229
      • 0.0458
      • 0.0300
      • 0.0258
      • 0.0261
      • 0.0261
      • 0.0249
      • 0.0261
      • 0.0268
      • 0.0258
    • 500:
      • 0.2160
      • 0.2082
      • 0.2080
      • 0.2021
      • 0.2429
      • 0.1938
      • 0.2099
      • 0.2019
      • 0.2121
      • 0.2060
    • 1000:
      • 0.7497
      • 0.9289
      • 0.8098
      • 1.0942
      • 0.9812
      • 0.7009
      • 0.7321
      • 0.7490
      • 0.8479
      • 0.7373
    • 5000:
      • 18.719
      • 18.785
      • 16.761
      • 17.603
      • 16.377
      • 16.580
      • 17.436
      • 16.925
      • 20.458
      • 17.971
    • 10000:
      • 65.756
      • 66.079
      • 65.697
      • 70.875
      • 65.729
      • 64.894
      • 65.837
      • 66.313
      • 68.960
      • 66.710
  • Map方式
    • 100:
      • 0.0270
      • 0.0239
      • 0.0310
      • 0.0249
      • 0.0258
      • 0.0449
      • 0.0288
      • 0.0241
      • 0.0258
      • 0.0251
    • 500:
      • 0.0717
      • 0.0720
      • 0.0712
      • 0.0688
      • 0.0700
      • 0.0710
      • 0.0727
      • 0.1088
      • 0.0842
      • 0.0710
    • 1000:
      • 0.125
      • 0.1308
      • 0.1279
      • 0.1350
      • 0.125
      • 0.1298
      • 0.3139
      • 0.1340
      • 0.1318
      • 0.1279
    • 5000:
      • 0.5861
      • 0.6101
      • 0.6982
      • 0.5981
      • 0.6020
      • 0.6130
      • 1.2448
      • 0.6088
      • 0.6169
      • 0.5859
    • 10000:
      • 2.934
      • 3.756
      • 2.924
      • 3.152
      • 2.929
      • 2.934
      • 3.286
      • 3.708
      • 3.067
      • 4.905
  • includes:
    • 100:
      • 0.0270
      • 0.0278
      • 0.0258
      • 0.0270
      • 0.0449
      • 0.0239
      • 0.0251
      • 0.0249
      • 0.0268
      • 0.0419
    • 500:
      • 0.1999
      • 0.3391
      • 0.2119
      • 0.2231
      • 0.2077
      • 0.2519
      • 0.2089
      • 0.2111
      • 0.2128
      • 0.2119
    • 1000:
      • 0.7868
      • 0.7189
      • 0.7338
      • 0.7248
      • 0.7419
      • 0.7338
      • 0.7048
      • 0.7902
      • 0.7370
      • 0.7829
    • 5000:
      • 17.931
      • 16.903
      • 17.624
      • 17.048
      • 17.359
      • 18.250
      • 17.650
      • 18.031
      • 18.659
      • 16.867
    • 10000:
      • 65.724

      • 70.203

      • 71.104

      • 68.052

      • 66.107

      • 67.373

      • 65.635

      • 71.907

      • 77.136

      • 69.695

结论:

对于数组的查找Map.has性能要远远好于indexOf,尤其大数据量上,如果可以,尽量选择使用Map.has进行判断是否存在