我有大约19.000项的数组。
我必须随机地通过任意id访问它们(也就是说,不需要遍历数组)
我只是想知道如果我使用id作为数组的索引,或者是否有任何类型的技巧或库来加速这些事情,js是否会优化代码。
更确切地说,我将在大约20,000所学校举行选举结果,我想知道你对哪一个会更快的建议:
[
{
school_id: xx
results: [
{
party_id: xx
votes: xx
}, [...]
]
}, [...]
]
[ // use school_id as index to the array
[
{
party_id: xx
votes: xx
}, [...]
], [...]
]
问题是js是否足够智能以优化阵列随机访问。
您可以建议我用来测试性能的任何工具都非常受欢迎
答案 0 :(得分: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]
注意命名字段如何与内部字段并排存储。如果您现在添加任何属性,它将会 进入第二个字段指向的外部属性数组,而不是直接存储在对象上。
带有整数键的“fields”将位于ElementsArrayPointer
指向的外部元素数组中,如下所示:
[HiddenClassPointer, TaggedSmallInteger(25), TheHolePointer, TheHolePointer, TheHolePointer, TheHolePointer, TheHolePointer, TaggedSmallInteger(5), TaggedSmallInteger(6), ...more hole pointers until 25 elements]
25是后备阵列的长度。我很快就会回来。
需要使用孔指针来消除用户给出的显式未定义值与数组中实际孔之间的歧义。当你尝试检索[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
答案 1 :(得分:0)
使用JSPerf编写测试。您可以使用它来测试许多不同的场景。