【问题标题】:Why are for..in faster than for loops when looping through an array为什么在遍历数组时 for..in 比 for 循环快
【发布时间】:2013-03-07 23:14:42
【问题描述】:

我一直想知道for 循环或for..in 循环在数组上的哪个位置更远。

我已经使用jsperf 对此进行了测试。

我的For 循环有16,676,377 op/s
for..in 只有519,853 op/s

那为什么是:

var a = ["hi", "hi2", "bye", "bye2"];

for (var i in a) {
  return a[i];
}

较慢:

var a = ["hi", "hi2", "bye", "bye2"];

for (var i = 0; i < a.length; i++) {
  return a[i];
}

【问题讨论】:

  • 他们做不同的事情(并且实现方式不同)。那么..有什么问题?
  • @pst,OP 不明白他们的不同之处。
  • 实际上你的退货声明有点破坏了一切
  • 增加一个计数器以获取下一个要解析的属性可能比搜索对象更有效,它是 [[Prototype]] 链,用于随后必须解析的可枚举属性。
  • 哈,我完全忘了回报要分手了。

标签: javascript arrays performance for-loop


【解决方案1】:

您的问题的答案很简单:for in 循环不是为了处理数组而创建的,它还做了其他事情,不应该使用。

for-in 语句的主要目的是迭代思想对象的属性,而不是通过数组。这个语句也会进入数组原型链,遍历继承的属性,我想你不需要这个甚至不知道这个。

另一个有趣的事情,你甚至不知道它会以什么顺序迭代。

所以要记住的主要事情 - 不要在数组中使用 for in。只有对象。

P.S as RobG 正确添加:

如果在数组中找不到属性,for 循环也会搜索 [[Prototype]] 链上的属性。例如。 [0,,2] 上的 for 循环将一直搜索 1 到 Object.prototype[[Prototype]]

【讨论】:

  • 如果在数组中没有找到 [[Prototype]] 链上的属性,for 循环也会搜索它们。例如。 [0,,2] 上的 for 循环将搜索 1 一直到 Object.prototype[[Prototype]]
【解决方案2】:

这里有几个问题。

  1. 循环主体中的return 导致循环在第一次迭代后中止,您的测试无用
  2. for..in 循环遍历对象的属性,数组的元素不是它唯一的属性!您是否添加了属性,例如a.foo = true;这将包含在使用 for..in 进行迭代中,但不会包含在 for 中。

请不要使用for..in 循环数组。不是。永远。

【讨论】:

    【解决方案3】:

    要解释为什么for 循环比for in 循环更快,基本上要了解用于将数据存储在内存中的底层数据结构。 由于数组存储在内存中的方式,循环遍历基于索引的数组自然会更快。它只是内存中的一个位置,数组中的项目存储在连续的位置,也就是。顺序并相邻。通常,按连续顺序检索元素会很快,因为您不必花时间找到它,您只知道下一个项目总是它旁边的下一个位置。并且因为它知道array.length 并且可以确定哪些内存块已被分配给数组。

    【讨论】:

    • 我认为没有任何理由相信 a[2] 的值一定会与 a[3] 相邻存储,或者这种存储一定比其他存储选项更快。性能上的差异更有可能只是优化 for 循环的实现选择,而不必太担心 for..in 循环,因为 for 循环的使用频率更高。
    • 我不知道他们是如何实现 JavaScript 引擎的,所以我不能肯定地说......但一般来说,数组速度很快,因为它们在内存中存储/访问的方式.
    【解决方案4】:

    这真的取决于 JavaScript 引擎的实现。因为 JavaScript 是动态类型的,解释器必须做一些工作来确定给定变量的类型。我怀疑引擎中针对经典整数迭代器 for 循环的优化在使用 for...in 时不可用。

    编辑:

    for..in 遍历变量的可枚举属性,因此 var i 在每个循环中都被分配了数组中每个字符串的值。

    【讨论】:

    • 真傻 - 我怎么会错过这个?
    猜你喜欢
    • 1970-01-01
    • 2022-06-12
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    相关资源
    最近更新 更多