在 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 thecallback
function once for every array index0..length-1
(inclusive) in the array until it finds one wherecallback
returns a truthy value.
emphasis mine
换句话说,一旦找到您要查找的项目,它就会停止。 indexOf
有类似的行为,因为它将返回找到的第一个项目的索引。
另一方面,查看map
:
map
calls aprovided
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/