javascript - 性能: findIndex vs Array.原型(prototype).map

标签 javascript arrays dictionary object indexing

在 2019 年,如果我正在处理一个长度在 15000 以上的对象数组,并且我需要按值查找对象的索引,则以下哪种方法将就性能而言是我的最佳选择吗?

六岁的“答案”:In an array of objects, fastest way to find the index of an object whose attributes match a search

查找索引

array.findIndex(object => foo === object.id);

Array.prototype.map

array.map(object => object.id).indexOf(foo);

最佳答案

从概念上讲,这两个片段实现了相同的目标,但它们的实现方式却截然不同。要了解这两个解决方案有何不同,我们首先看一下 findIndex :

The findIndex method executes the callback function once for every array index 0..length-1 (inclusive) in the array until it finds one where callback returns a truthy value.
emphasis mine

换句话说,一旦找到您要查找的项目,它就会停止。 indexOf有类似的行为,因为它将返回找到的第一个项目的索引。

另一方面,查看map :

map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results.
emphasis mine

换句话说,map 并不关心您要搜索的项目。即使您要查找的项目是数组中的第一项,map 仍会循环遍历 14999 个其他项目,以创建一个新的 id 数组。这意味着您最终需要做更多的工作才能获得相同的结果,无论是在时间复杂性(循环所有这些项目需要更多时间)还是空间复杂性(存储临时数组需要更多内存)方面。

旁注:如果您使用iterators / generators,则上述不一定正确。 ,在某种意义上可以“展望 future ”,看看是否需要做更多的工作。但我认为这超出了这个问题的范围。

但是,如果您确实关心性能,那么亲自运行测试总是一个好主意。这是一个快速基准测试,用于展示两种实现的相对性能。在我的机器上,我得到 findIndex: 0.023ms/map+indexOf: 0.572ms。您的里程可能会有所不同:

var suite = new Benchmark.Suite();

const haystack = [];
let needle;

suite
  .add('findIndex', () => haystack.findIndex(o => o.id === needle))
  .add('map+indexOf', () => haystack.map(o => o.id).indexOf(needle))
  .on('start', () => {
    for (let i = 0; i < 15000; i++) {
      haystack.push({
        id: Math.random().toString(36).substring(7)
      });
    }
    console.log('Starting test.');
  })
  .on('cycle', () => {
    needle = haystack[Math.floor(Math.random() * haystack.length)].id;
  })
  .on('complete', () => {
    console.log('Test results (lower is better):')
    suite.forEach((bench) => {
      console.log(`  ${bench.name}: ${(bench.stats.mean * 1000).toFixed(3)}ms`);
    });
  })
  .run({
    'async': true
  });
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.min.js"></script>

关于javascript - 性能: findIndex vs Array.原型(prototype).map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55246694/

相关文章:

c - 数组和C语言中的指针到底有什么区别?

javascript - 在多维数组中查找条目,其中属性的一部分与给定文本匹配

ios - 根据条件将数组合并到字典中?

python - 无法修复未对齐的结果

javascript - 如何只显示多个下拉值数组中的1个?

c++ - 如何在多个函数中使用同一个多维数组?

javascript - 使用 jquery 迭代值的问题

python - 从多个文件访问和编辑字典

javascript - sapui5复杂数据绑定(bind)

javascript - Mongodb findOne查询不会停止