すべて32ビットに収まる3つの個別の値がある場合、UINTを使用してそれらを保存することは理にかなっていますか?
-
01-10-2019 - |
質問
私が意味するのは、私が持っていると言っています struct
いくつかのデータを表すために、それは次のようになります:
struct LilStruct
{
public readonly short A;
public readonly byte B;
public readonly byte C;
public LilStruct(short a, byte b, byte c)
{
A = a;
B = b;
C = c;
}
}
a short
と2 byte
値はすべて32ビットに収まる可能性があります。私が疑問に思っているのは(アラインメントの目的、パフォーマンスなど)、このデータを次の形式で保存するのが実際に理にかなっているかどうかです。
struct LilStruct
{
private readonly uint _value;
public LilStruct(short a, byte b, byte c)
{
_value = ((uint)a << 16) | ((uint)b << 8) | (uint)c;
}
public int A
{
get { return (int)(_value >> 16); }
}
public int B
{
get { return (int)(_value >> 8) & 0x000000FF; }
}
public int C
{
get { return (int)(_value & 0x000000FF); }
}
}
これは無意味ですか?利点/欠点は何ですか?
解決
.netで、あなたが使用するとき struct
とにかく、あなたは構造体を飾ることができます StructLayoutAttribute
このような:
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct LilStruct
{
public readonly short A;
public readonly byte B;
public readonly byte C;
public LilStruct(short a, byte b, byte c)
{
A = a;
B = b;
C = c;
}
}
これは、フィールドが順番にレイアウトされるという効果があります。たとえば、フィールド B
オフセット16から始まります。
の値1の値 Pack
フィールドがに整列されていることを意味します byte
境界。
他のヒント
値が互いに密接に結びついており、通常は一緒に渡され、互いに独立して修正されることはない場合にのみ、複数の値をUINTに詰め込むことを検討する必要があります。 UINTを開梱して再梱包するコストは、その値を変更するために、3バイトを個別に保存するのと比較して(コードサイズと実行時間)非常に高価になります。
合計10KバイトのRAMでマイクロデバイスで実行する場合、メモリは実行速度よりも貴重であるため、このような梱包は価値があるかもしれません。通常のデスクトップPCや携帯電話デバイスでさえ、この梱包はおそらく努力する価値がないでしょう。
構造定義にとどまり、 structlayout との属性 structlayoutattribute.pack 1の値は、実際には、アクセス速度を犠牲にして少しのメモリを保存するでしょう。これにより、アクセスが最も効率的な方法でデータがメモリにレイアウトされないためです。コンパイラは通常、アクセスするのに効率的で、自動的にあまり多くのメモリを台無しにしない方法でメモリをレイアウトします。
このアプローチは、少なくともあなたが提案したビットシフトアプローチよりもコードをより理解しやすく保ちます(実際、マシンコードコンパイラがバイトコードから生成するものと依然として類似している場合もあります)。
遭遇するのは、メモリ内データオブジェクトのサイズと処理コストの間の簡単なトレードオフです。メモリが本当の懸念事項である場合、マシンにさらにラムを投げる方が安いかもしれません。
整数に物を詰め込む価値がある場合はいくつかあります。ストレージスペースだけでは通常正当な理由ではありませんが、辞書のキーとして値を一緒に使用する場合、辞書(整数、何であれ)が辞書(静止物、何でも)よりもはるかに高速になります。