为什么原生数组函数比循环慢?

26

这个问题已经在标题中了,但以下是更详细的解释。

很久以前,我学会了一些不错的JavaScript函数,例如reduce、filter、map等等。我真的很喜欢它们,并开始频繁使用它们(它们看起来很时髦,我认为由于它们是本地函数,所以它们应该比我的旧for循环更快)。

最近我需要执行一些复杂的js计算,所以我决定检查它们的速度有多快,但令我惊讶的是它们不是更快,相反,它们慢得多得多(从3倍到25倍慢)

此外,我没有针对每个函数进行检查,但这里是我的jsperf测试:

那么为什么本地函数比旧循环慢得多,如果它们没有做任何更好的事情,那么创建它们的目的是什么。

我认为速度损失是由于函数在其中被调用,但这并不能证明这种损失。而且我看不出为什么使用这些函数编写的代码更易读,更不用说它们并不受到每个浏览器的支持。

这是一个有趣的问题,但我怀疑它与浏览器内部有关(以及由于最近的创建/实现可能缺乏优化),而不是代码问题本身;我不会投票关闭(因为我对答案感兴趣),但这种潜在的开放式讨论可能更适合[programmers.se]。 - David Thomas
有趣!!所有浏览器都很慢吗? - Konza
我只有在火狐浏览器中使用Chrome(而且速度较慢),但你可以在IE或Opera中自行测试。 - Salvador Dali
.filter - 噢,它比循环慢了10倍(在FF中被忽略了):http://jsperf.com/filter-and-loop/4 - zerkms
1
@SalvadorDali 首先,你可以去(例如)v8 bug跟踪器查看问题的优先级,这是完全公开的。代码库以及围绕它的讨论也是公开的。至于作为开发人员,我不是任何一个浏览器的“核心”开发人员。虽然我碰巧有一些正在研究不同浏览器的朋友,但我想强调的是,接触这些人并不特别困难,你可以轻松地(并且欢迎!)参与,并且欢迎提出困扰你的问题并帮助https://code.google.com/p/v8/wiki/Contributing。 - Benjamin Gruenbaum
显示剩余5条评论
1个回答

2

我认为,这些本地函数更多的是糖而不是优化。

这不同于使用 Array.prototype.splice 而不是自己循环执行它,后者的实现显然能够在内存中执行的操作比你自己能做的要多得多。

在某个时间点上,使用 filter、reduce 和 map 时,浏览器将必须循环遍历数组并对其中包含的值执行某些操作(就像您使用循环一样)。它不能减少实现相同目的所需的工作量(仍在循环并执行操作),但它可以提供更令人愉悦的 API,并提供错误检查等功能,这将增加时间。


1
语言中的语法糖只是另一种结构的包装器,因此它们不会有如此大的计算惩罚。 - Salvador Dali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接