将两个数字组合起来用作对象的键的有效方法是什么?

时间:2014-11-27 02:08:06

标签: javascript performance dictionary data-structures hash

我使用以下模式将注释从数字对编号转换为数字:

var myHash = {};
...
for (... billion of iterations ...)
    var x = someNum;
    var y = otherNum;
    myHash[x + "," + y] = z;

这段代码的问题在于我使用字符串作为myHash的键,它已被测试为慢于整数键。我的问题是:在将2个数字用作对象的键之前,将两个数字组合起来的更聪明的方法是什么? I.E.,如何将2个双打组合成一个独特的整数?

1 个答案:

答案 0 :(得分:2)

JavaScript中有一个数组的定义:

  

Array对象对某类属性名称进行特殊处理。当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于2 32 时,属性名P(以String值的形式)是数组索引 - 1.属性名称为数组索引的属性也称为元素。每个Array对象都有一个length属性,其值始终是小于2 32 的非负整数。 length属性的值在数值上大于名称为数组索引的每个属性的名称;无论何时创建或更改Array对象的属性,都会根据需要调整其他属性以保持此不变量。具体来说,每当添加名称为数组索引的属性时,如果需要,将更改length属性,使其大于该数组索引的数值;每当更改length属性时,将自动删除名称为数值索引且值不小于新长度的每个属性。此约束仅适用于Array对象的自身属性,并且不受可能从其原型继承的长度或数组索引属性的影响。

换句话说,如果您指定的索引是表示0到0xFFFFFFFE之间的整数的数字,那么它将用作数组索引。任何其他值都被视为字符串,它用于创建对象成员而不是数组项。

因此,如果您的索引上有一些符合有效范围(0到0xFFFFFFFE)的约束,那么您就是好的。否则,你所拥有的可能是最快的。

所以下面表示作为对象myHash的成员的字符串索引:

myHash[x + "," + y] = z;

有人提到使用数组数组。那对你没有帮助。你会得到很多数组而不是很多字符串。如果不慢,它可能会大致相同。这个想法是这样的:

myHash[x] = [];  // initialize the sub-array (must be done only once per value of 'x'
myHash[x][y] = z;   // save z in that array

我不建议使用double数组,因为它会在myHash之上为每个'x'值初始化一个数组,这可能不会比使用字符串连接更快(特别是因为你必须测试myHash [x]数组已定义或未定义......)。

所以...可以写:

myHash[3.3] = "that worked?";

但如果在那之后检查长度,你会发现它是零:

console.log("Hash length = " + myHash.length);

这是因为3.3不是整数。