Javascript 性能:findIndex vs Array.prototype.map

Javascript 性能:findIndex vs Array.prototype.map,javascript,arrays,dictionary,object,indexing,Javascript,Arrays,Dictionary,Object,Indexing,2019年,如果我处理一个长度为15000的对象数组,并且我需要按值查找对象索引,那么以下哪种方法将是我最佳的性能选择 六岁的“答案”: findIndex array.findIndex(object => foo === object.id); Array.prototype.map array.map(object => object.id).indexOf(foo); 从概念上讲,这两个代码片段实现了相同的目标,但它们的方式非常不同。要了解这两种解决方案的不同之处,让我们

2019年,如果我处理一个长度为15000的对象数组,并且我需要按值查找对象索引,那么以下哪种方法将是我最佳的性能选择

六岁的“答案”:

findIndex

array.findIndex(object => foo === object.id);
Array.prototype.map

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

从概念上讲,这两个代码片段实现了相同的目标,但它们的方式非常不同。要了解这两种解决方案的不同之处,让我们首先看看:

findIndex
方法对数组中的每个数组索引
0..length-1
(包括)执行一次
callback
函数,直到找到其中一个
callback
返回真实值
重点矿山

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

另一方面,看看:

map
为数组中的每个元素调用一次
提供的
回调函数,然后根据结果构建一个新数组。
重点矿山

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

旁注:如果您使用,上述内容不一定是正确的,这可以在某种意义上说是“向前看”,看看是否需要更多的工作。但我认为这超出了这个问题的范围

然而,如果您真的关心性能,那么为自己运行测试总是一个好主意。这里有一个快速的基准测试来演示这两个实现的相对性能。在我的机器上,我得到
findIndex:0.023ms
/
map+indexOf:0.572ms
。您的里程可能有所不同:

var-suite=newbenchmark.suite();
常量haystack=[];
让针;
一套
.add('findIndex',()=>haystack.findIndex(o=>o.id==needle))
.add('map+indexOf',()=>haystack.map(o=>o.id).indexOf(针))
.on('start',()=>{
for(设i=0;i<15000;i++){
干草堆({
id:Math.random().toString(36).子字符串(7)
});
}
console.log(“启动测试”);
})
.on('循环',()=>{
针=草堆[Math.floor(Math.random()*haystack.length)].id;
})
.on('完成',()=>{
log('测试结果(越低越好):')
套房(长凳)=>{
log(`${bench.name}:${(bench.stats.mean*1000.toFixed(3)}ms`);
});
})
.跑({
“异步”:true
});


毫无疑问
findIndex
您可能只需要为此编写一个jsperf。您的第二个方法在列表上进行两次线性传递,并构造一个新数组。不是轻率,而是:尝试一下。另外,还有一个方法提到了
findIndex
。一个问题老了并不意味着它的答案没有价值。谢谢你的全面回答