有没有办法在 JS 对象的键上保存 space?

Is there a way to save space on keys of JS objects?

我刚刚想到了以下情况:

假设我们有如下所示的线定义。这里开始和结束都是点。

let line = {
    start: {x:0, y:0},
    end: {x:0,y:0},
    orientation: 'vertical'
}

现在假设我们有一个非常大的行数组,我们如何保存 space?我知道您可以用枚举替换方向值 'vertical'。但是你能在不降低可读性的情况下在键名上保存 space 吗?例如,您可以将 orientation 替换为 o,但现在不再清楚密钥代表什么。

告诉我!

如果你指的是内存使用,Javascript 现在的引擎非常聪明,比如在内部使用查找键,字符串 de-duplication 等,使得短键名或长键名都很少效果。

例如,使用您上面的数据结构,我将 100 万条记录放入一个数组中,一条具有很长的键名,另一条具有 1 个字符的键名。在这两种情况下,每个项目的内存使用量约为 147 字节。同样,即使对 vertical 使用 const 也收效甚微。

但是如您所见,147 字节似乎确实很高,因此如果您想减少它,则需要使用 TypedArrays,不幸的是,这些可能有点难以推理。但如果内存是一个值得关注的问题。

如果您确实使用了 TypedArray,则可以使用 getter 和 setter 使这更容易。这样做你可能每条记录使用 33 个字节,4 个双精度数和 1 个字节。

但在做任何事情之前,我会首先确保进行这种优化是必要的。 Pre-Optimising Javascript 是傻子差事。

ps。我使用 NodeJs 进行了内存测试,它基本上使用 Chrome 的 Javascript 引擎。

此外,如果您想了解内存是如何影响的,并且您安装了 NodeJs,这里有一些示例代码可以帮助您入门。

const oused = process.memoryUsage().heapUsed;

const values = [];
for (let l = 0; l < 1000000; l += 1) {
    values.push({
        start: { x: 0, y: 0 },
        end: { x: 0, y: 0 },
        orientation: "vertical",
    });
}

console.log(process.memoryUsage().heapUsed - oused);

这是在可用性和内存效率之间取得平衡的线条表示。它不使用字符串标识符,因为数据的位置被编码到类型中。它还使用标准数组,因为您没有指定笛卡尔坐标平面的大小(所以我不能建议像 TypedArray 这样的有界容器):

TS Playground

type Point = [x: number, y: number];

type Line = [a: Point, b: Point];
const line: Line = [[0, 0], [0, 2]];

// More memory efficient: 2 fewer arrays per line:
type CompactLine = [...a: Point, ...b: Point];
const compactLine: CompactLine = [0, 0, 0, 2];

我建议您为所有缩短版本的键创建一个映射,并将该映射与您的对象并行使用。映射可以将对象键作为映射键,将完整形式作为值

const map = new Map()
const object = {
  o: 4
} // o means orientation
map.set("o", "orientation")
const mapKeys = Array.from(map.keys())
const redeableObj = {}
mapKeys.forEach(key => {
  const redeableKey = map.get(key)
  redeableObj[redeableKey] = object[key]
})
console.log(object)
console.log(redeableObj)