-1

我有大约 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 是否足够聪明以优化数组随机访问。

您可以建议我用来测试性能的任何工具都将受到欢迎

4

2 回答 2

1

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

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

因此,当您这样做时,是 Javascript Array 对象还是任何 javascript 对象obj[5]都没有关系- 它会访问对象的外部元素数组。obj

因此,如果您创建了这样的对象:

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) + 16so 6 + 7/2 + 16 = 25。您可以在堆快照中看到它。

在此处输入图像描述

( 108 - 8 ) / 4 === 25
于 2013-09-20T09:41:31.367 回答
0

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

于 2013-09-20T03:32:39.070 回答