有没有办法在 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 这样的有界容器):
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)
我刚刚想到了以下情况:
假设我们有如下所示的线定义。这里开始和结束都是点。
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 这样的有界容器):
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)