Si j'ai trois valeurs distinctes qui pourraient tous en forme 32 bits, est-il logique d'utiliser un uint pour les stocker?

StackOverflow https://stackoverflow.com/questions/3587593

Question

Ce que je veux dire, que j'ai un struct pour représenter des données et il ressemble à ceci:

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 et deux valeurs de byte pourrait tout ajustement en 32 bits. Ce que je me demande est (à des fins d'alignement, la performance, peu importe) si elle serait effectivement judicieux de le stocker ces données dans le format suivant à la place:

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); }
    }
}

Est-ce inutile? Quels seraient les avantages / inconvénients?

Était-ce utile?

La solution

Dans .NET, lorsque vous allez utiliser un struct de toute façon, vous pouvez aussi bien décorer la struct avec StructLayoutAttribute comme ceci:

[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;
    }
}

Cela aura pour effet que les champs sont disposés de manière séquentielle, par exemple champ B commencera à 16 offset.

Une valeur de 1 pour Pack signifie que les champs sont alignés aux limites de byte.

Autres conseils

Vous ne devez considérer entasser plusieurs valeurs dans un uint si les valeurs sont étroitement liées les unes aux autres, le plus souvent passé autour ensemble, et ne sont jamais ou très rarement modifiés indépendamment les uns des autres. Le coût de déballage et remballage uint afin de modifier sa valeur rend ce très cher (la taille du code et le temps d'exécution) par rapport à seulement stocker trois octets séparément.

Lors de l'exécution sur un micro avec un total de 10K octets de RAM, d'emballage comme cela pourrait valoir la peine parce que la mémoire est plus précieuse que la vitesse d'exécution. Sur un PC de bureau normal ou même dispositif de téléphone mobile, cet emballage est probablement pas la peine.

scroll top