据说
javascript 中的所有数字都是 64 位浮点数。
我想知道数字是否总是在内存中使用 64 位?
我有这样的数据结构(在 C 风格的代码中)
{
int x; // [0-9]
int y; // [0-9]
int d; // [0-3]
}
x 和 y 将绝对在 [0-9] 的范围内,并且 d 的唯一可能值是 0、1、2、3。
如果我将它们存储为 3 个分隔数字,该结构会使用 64 位 * 3 = 192 位 = 24 字节吗?
如果是这样,我想将它存储在一个数字中,x * 100 + y * 10 + d,这应该只使用 64 位(8 字节)。在不考虑 CPU 使用率的情况下这是否更好。
我还考虑了字符串解决方案。
x.toString() + y.toString() + d.toString();
因为所有的 x、y 和 d 都小于 10,所以它们应该只有 1 个字符,16 位。所以结构变成 16 bits * 3 = 48 bits = 6 Bytes。这是最优化存储的解决方案吗?
那么mongoDB中的存储呢?如果我将数据结构存储到mongoDB中,是不是同样的情况?
我写了一个片段来测试 mongo 中的存储。最终结构包括上述结构的 3 个实例。总量为66816。
我将它们存储到 3 个独立的数据库中:
- 布局完整(我丢失了一个's'):一个数组包括 3 {x: valueX, y: valueY, d: valueD}
- layouts-int: xydxydxyd (十进制) ex. 233250750 表示 {x:2,y:3,d:3},{x:2,y:5,d:0},{x:7,y:5,d:0}
- layouts-str:将上面的 int 转换为 2-char 字符串。String.fromCharCode(i >> 16) + String.fromCharCode(i & 0xFFFF)
结果是……
> show dbs
layout-full 0.03125GB
layouts-int 0.03125GB
layouts-str 0.03125GB
但细节是...
布局完整的集合
"size" : 8017920,
"avgObjSize" : 120,
"storageSize" : 11182080,
layouts-int 中的集合
"size" : 2138112,
"avgObjSize" : 32,
"storageSize" : 5591040,
layouts-str 中的集合
"size" : 2405396,
"avgObjSize" : 36.000299329501914,
"storageSize" : 5591040,
从这些结果中,我发现 int 存储是最节省空间的方法。
我也这样做了:
> db.tiny.save({})
> db.tiny.stats().avgObjSize
24
> db.tiny.remove()
> db.tiny.save({l:null})
> db.tiny.stats().avgObjSize
28
> db.tiny.remove()
> db.tiny.save({l:[{x:null,y:null,d:null},{x:null,y:null,d:null},{x:null,y:null,d:null}]})
> db.tiny.stats().avgObjSize
84
所以_id
将使用 24 个字节,而关键部分 ,{l:
将使用 4 = 28 - 24 个字节。
而且你会发现一个整数使用 32 - 28 = 4 个字节,所以小于 2^31 的整数似乎在 mongo db 中存储为 32 位整数。
还有 in string 解决方案,一个 2-char 字符串使用 36 - 28 = 8 个字节,正好等于我猜到的值。
而对于全结构解决方案,从上次的 tiny db 测试中,您可以看到没有数据的结构使用 84 字节,因此数据使用 120 - 84 = 36 字节 = 9 * 4 字节。我的最终数据结构中只有 9 个整数(三元组 x、y、d)。这也证明整数存储为 32 位整数。
为什么空结构使用 84 字节?
通过一些更多的实验,我发现1个数组或空json对象使用4个字节,而一个键使用* 4。
所以,空结构实际上是
{ // 1 object +4 bytes = 4
'_id': ObjectId('0123456789abcdef012345678'), // 3-char key + 12-byte id = 24
'l': [ // 1-char key + 1 array = 8
{'x': null, 'y': null, 'd': null}, // 1 object+ 3 keys = 16
{'x': null, 'y': null, 'd': null}, // 1 object+ 3 keys = 16
{'x': null, 'y': null, 'd': null} // 1 object+ 3 keys = 16
]
}
结果是 4 + 24 + 8 + 16 * 3 = 84 字节。
我希望我的实验对其他人有用。