【问题标题】:Fastest Way of Using Coordinates as Keys in Javascript Hashmap在 Javascript Hashmap 中使用坐标作为键的最快方法
【发布时间】:2016-12-24 15:39:38
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 部分我可以回答...... JavaScript 位运算符都适用于 16 位整数
  • 你必须使用哈希映射吗?假设坐标是整数,为什么不使用二维数组?甚至是 2D 哈希图。如果您使用数组,则可以预先分配键并节省每次遇到新位置时添加唯一键的成本。
  • 坐标的最大尺寸是多少?它是什么类型的坐标(GPS坐标、网格坐标等)?
  • 你需要这个做什么?我想不出我需要/使用这种结构(按位置缓存点)的情况?如果我需要按位置存储点,我可能会使用四叉树。
  • @MikeC,你是对的!我可以使用一个数组。在上下文中,它用于 2D 游戏卡盘,其中需要加载随机的卡盘,因此该数组会浪费一些空间

标签: javascript performance hashmap hashtable


【解决方案1】:

您可以使用以下解决方案将一对坐标组合成一个 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);

【讨论】:

    猜你喜欢
    • 2013-08-23
    • 2021-10-28
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 2017-05-16
    • 2017-08-26
    相关资源
    最近更新 更多