と言われている
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 という 1 つの数値に格納したいと思います。これは 64 ビット (8 バイト) のみを使用する必要があります。CPU使用率を考慮しない方が良いですか?
また、文字列ソリューションについても検討しました。
x.toString() + y.toString() + d.toString();
x、y、d はすべて 10 未満であるため、1 文字、16 ビットである必要があります。したがって、構造は 16 ビット * 3 = 48 ビット = 6 バイトになります。これは最もストレージに最適化されたソリューションですか?
mongoDB のストレージはどうですか? データ構造を mongoDB に格納すると、同じ状況になりますか?
mongo でストレージをテストするためのスニペットを作成しました。最終的な構造には、上記の構造の 3 つのインスタンスが含まれます。合計金額は 66816 です。
それらを3つの別々のデータベースに保存しました:
- layout-full ('s' を失いました): 配列には 3 つの {x: valueX, y: valueY, d: valueD} が含まれます
- layouts-int: xydxydxyd (10 進数) ex. 233250750 は {x:2,y:3,d:3},{x:2,y:5,d:0},{x:7,y:5,d:0} を意味します
- layouts-str: 上記の int を 2 文字の文字列に変換します。文字列.fromCharCode(i >> 16) + 文字列.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 ビット整数として格納されるようです。
また、文字列内のソリューションでは、2 文字の文字列は 36 - 28 = 8 バイトを使用し、私が推測した値とちょうど同じです。
また、完全な構造のソリューションでは、最後の tiny db テストから、データのない構造は 84 バイトを使用することがわかります。したがって、データは 120 - 84 = 36 バイト = 9 * 4 バイトを使用します。そして、最終的なデータ構造 (トリプル x、y、d) には 9 つの整数しかありません。これは、整数が 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 バイトです。
私の実験が他の人に役立つことを願っています。