在Javascript Hashmap中使用坐标作为键的最快方法

时间:2016-08-17 20:33:49

标签: javascript performance hashmap hashtable

我想使用它们的坐标存储对象,如下所示:

var hash_map = {};
hash_map[x + "-" + y] = new Object();

然后可以使用hash_map[x + "-" + y]检索这些内容。

但是,我不确定每次访问对象时是否创建新字符串都是一个好主意。

另一种方法是通过执行类似x | (y >>> 16)的操作来组合坐标,但我不知道将y值移位多少位,内部实际发生的事情(因为javascript的数字都是浮动,所以有一个指数和尾数等)以及它是否真的值得。

tl; dr在坐标为键的哈希映射中存储对象的最快方式(包括垃圾收集)是什么?

1 个答案:

答案 0 :(得分:4)

您可以使用以下解决方案将一对坐标复合为一个32位有符号整数。然后可以将此整数用作JS对象的键。 2坐标最多只能是16位。因此,x和y只能包含-32767到+32767(2 ^ 15-1)的值。

在下面的示例中,生成100个随机坐标对,并将其添加到hash_map对象,其值包含从键计算的x和y坐标。坐标必须在上述范围内,否则将抛出异常。

var MAX_16BIT_SIGNED = 32767; //Math.floor((Math.pow(2, 16)/2)-1);

function getRandomIntInclusive(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getRandomKey() {
  var x = getRandomIntInclusive(MAX_16BIT_SIGNED * -1, MAX_16BIT_SIGNED),
    y = getRandomIntInclusive(MAX_16BIT_SIGNED * -1, MAX_16BIT_SIGNED);

  //console.log("Generated key with x: " + x + " and y: " + y);
  return getKey(x, y);
}

function getKey(x, y) {
  if (x > MAX_16BIT_SIGNED || y > MAX_16BIT_SIGNED)
    throw "Invalid X or Y value.";
  x += MAX_16BIT_SIGNED;
  y += MAX_16BIT_SIGNED;
  return (x << 16) | y;
}

function getX(key) {
  return (key >> 16) - MAX_16BIT_SIGNED;
}

function getY(key) {
  return (key & 0xFFFF) - MAX_16BIT_SIGNED;
}

var hash_map = {};
hash_map[getKey(MAX_16BIT_SIGNED * -1, MAX_16BIT_SIGNED)] = "test";
hash_map[getKey(MAX_16BIT_SIGNED, MAX_16BIT_SIGNED)] = "test";
hash_map[getKey(MAX_16BIT_SIGNED * -1, MAX_16BIT_SIGNED * -1)] = "test";
hash_map[getKey(MAX_16BIT_SIGNED, MAX_16BIT_SIGNED * -1)] = "test";
//hash_map[getKey(MAX_16BIT_SIGNED+1, MAX_16BIT_SIGNED+1)] = "test";

for (var i = 0; i < 100; i++) {
  var key = getRandomKey();
  hash_map[key] = {
    x: getX(key),
    y: getY(key)
  };
}
console.log(JSON.stringify(hash_map));
console.log(100 === Object.keys(hash_map).length);