【问题标题】:js: which is faster? array or object accessjs:哪个更快?数组或对象访问
【发布时间】:2013-09-20 03:30:33
【问题描述】:

我有一个大约 19.000 个项目的数组。

我必须通过任意 id 随机访问它们(也就是说,不需要遍历数组)

我只是想知道如果我使用 id 作为数组的索引,js con 是否会优化代码,或者是否有任何技巧或库来加速这类事情。

更准确地说,我将获得大约 2 万所学校的选举结果,我想知道您对哪一所更快的建议:

[
  {
    school_id: xx
    results: [
      {
        party_id: xx
        votes: xx
      }, [...]
    ]
  }, [...]
]

[   // use school_id as index to the array
  [
    {
      party_id: xx
      votes: xx
    }, [...]
  ], [...]
]

问题是js是否足够聪明,可以优化数组随机访问。

欢迎您建议我用来测试性能的任何工具

【问题讨论】:

  • 用jsperf写一个测试
  • 数组实际上也是对象(哈希表)。你可以使用任何一个,这真的没关系。但是如果你选择使用一个对象,它就没有数组方法(不继承自 Array)。我可能把你弄糊涂了。只需使用数组。

标签: javascript arrays performance performance-testing


【解决方案1】:

这些问题始终取决于引擎。在 V8(谷歌浏览器、Node.js)中:

对象和数组并没有根本的不同。为了实现简单,所有对象都有一个外部元素数组,其中存储了正整数的属性。

所以当您执行obj[5] 时,obj 是 Javascript 数组对象还是任何 javascript 对象都没有关系 - 它会访问对象的外部元素数组。

所以如果你创建了一个这样的对象:

var a = {
    a: 3,
    b: 4,
    c: {},

    5: 5,
    6: 6
};

对象布局将是:

[HiddenClassPointer, PropertiesArrayPointer, ElementsArrayPointer, TaggedSmallInteger(3), TaggedSmallInteger(4), JSObjectPointer]

注意命名字段如何与内部字段并排存储。如果您现在在事后添加任何属性,它将 进入第二个字段指向的外部属性数组,而不是直接存储在对象上。

带有整数键的“字段”将位于ElementsArrayPointer 指向的外部元素数组中,如下所示:

[HiddenClassPointer, TaggedSmallInteger(25), TheHolePointer, TheHolePointer, TheHolePointer, TheHolePointer, TheHolePointer, TaggedSmallInteger(5), TaggedSmallInteger(6), ...more hole pointers until 25 elements]

25 是后备数组的长度。我很快就会回来。

需要空洞指针来区分用户给出的显式未定义值和数组中的实际空洞。当您尝试检索 a[3] 时,它将 回你undefined,因为有一个洞。所以实际的孔对象不会返回给用户。所以实际上有 3 种不同类型的 null :P

25的初始长度来自公式(initial index + 1 ) + ((initial_index + 1 ) / 2) + 16所以6 + 7/2 + 16 = 25。您可以在heap snapshot 中看到它。

( 108 - 8 ) / 4 === 25

【讨论】:

    【解决方案2】:

    使用JSPerf 编写测试。您可以使用它测试许多不同的场景。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多