我是一名V8开发者。 Array.prototype.find
的时间复杂度是O(n)(其中n为数组的长度),可以合理地假设它将保持不变。
一般来说,引擎往往无法改进操作的复杂度类别。 在Array.prototype.find
的情况下,您传递的谓词函数可能会关心其被调用的频率:
[1, 2, 3].find((value, index, object) => {
console.log(`Checking ${value}...`);
return value === 42;
});
在这种情况下,引擎别无选择,只能按照正确的顺序迭代整个数组,因为任何其他方式都会观察到程序行为的异常。
理论上,由于JS引擎可以进行动态优化,它们可以检查谓词函数,并且如果它没有副作用,它们可以使用它来构建某种索引/缓存。除了构建适用于任意谓词的系统的难度之外,即使这种技术起作用,它也只会加速对相同数组和相同函数进行重复搜索时的搜索,以代价浪费时间和内存,如果这完全相同的情况不会再次发生,那么显然是不划算的。似乎很难让引擎以足够的信心做出这种预测,以证明投资这些时间和内存是有价值的。
一条经验法则是:
在操作大型数据集时,选择高效的算法和数据结构是值得的。通常比我们在Stack Overflow问题中看到的微观优化要更具价值 :-)
高度优化的引擎可能能够使您的O(n)代码的速度快10%至10倍不等。通过转换为O(log n)或O(1)解决方案,您可以将其加速数倍。通常通过做一些引擎无法自动完成的操作来实现。例如,您可以保持数组已排序,然后在其上使用二分搜索--这是引擎无法自动为您完成的,因为显然它不允许重新排序您的数组内容而没有经过您的批准。正如@myf在评论中指出的那样:如果您想通过唯一键访问某些内容,则使用Map可能比使用Array更好。
也就是说,简单的解决方案往往比我们直觉所认为的更具可扩展性;我们对过早优化的标准警告也适用于这里以及其他任何地方。通过数组进行线性搜索通常就足够了,只有在有三个或更多项时才需要(散列)图。当存在疑虑时,请分析您的应用程序以找出性能瓶颈所在。
find
实现... - Heretic Monkey