1

私は任意の3つの値を取ることができる変数を持っています。2つの値しか取れない場合は、ブール型を割り当てます。しかし、私の変数は3つの値を取ることができます。int8_tタイプを割り当てると、6ビットが無駄になります。これはプリエンプティブ最適化のように見えますが、このタイプのインスタンスが何百万もあり、メモリ使用量に大きな違いが生じます。

全体的に使用されるメモリが最小になるように、変数をどのデータ型に割り当てる必要がありますか。

列挙型でそれを行う場合、それはより少ないメモリが使用されることを保証しますか?

特に、C、Java、Python、MySQLでどのデータ型を使用する必要がありますか。

4

2 に答える 2

3

ここに少し数学があります。単純に、各要素を2ビットで記述できるので、4つの要素を1バイトにパックして、適切なランダムアクセスを取得できます。4つの要素には34 =  81の状態があるため、81 /256≈32%の使用量になります。バイト境界にとどまりたい場合は、2 8に収まる最も近い3の累乗、つまり3 5  = 243を探すことができます。つまり、1バイトで5つの連続する要素のすべての可能な状態を列挙する場合、243 /256≈95%のスペース効率があります。

大量のデータを処理していて、すべてを物理メモリ収めることができず、アルゴリズムを分割して一度に小さなチャンクで実行できない場合を除いて、このパッキングをメモリで行うことは意味がありません。効率的な計算を行うには、少なくとも1バイト(uint8_t)、またはマシンワード(uint8fast_t)を使用してデータを格納する必要があります。データをディスクにシリアル化し、テラバイト単位のデータがRAID-50ストレージに対して高すぎることがわかった場合にのみ、複雑なパッキングスキームを検討することをお勧めします。(ただし、データをパイプでつなぐこともできgzipます。これにより、基本的にすべてが実行されます。)


バイトから5つの要素を取得するための基本的なデコードアルゴリズムは次のとおりです。

unsigned int get_tristate(unsigned char const n, size_t const i)
{
  /* Conditions:   n in [0, 243)
                   i in [0, 5)

     Returns: the i^th trivalent element encoded in n, in [0, 2).
  */

    static unsigned int const powers[] = { 1, 3, 9, 27, 81, 243 };

    return (n / powers[i]) % powers[i + 1];
}
于 2013-02-16T10:33:59.920 に答える
3

本当に(そうであるかどうかはわかりませんが)このデータ型が必要な場合は、ビットフィールドを使用できます。ただし、そのような型へのポインタを定義できないため、これは制約になる可能性があります。少し無駄に:

struct s
{
  int n:2; /* 4 states instead of 3 */
};
于 2013-02-16T10:28:12.250 に答える