Question

J'ai écrit récemment un code qui utilise le même court non signé pour stocker deux valeurs, un résultat et une carte d'identité, par exemple:

unsigned short data = new_id();
// result is either 0 or 1 so store it in the rightmost bit and move the id left
data = (data << 1) + get_result();
// ... later ...
// now we can print results like
printf("%u: %u\n", data & 1, data >> 1);

Serait-il préférable d'utiliser simplement une struct pour tenir les deux valeurs ou est ce genre de chose commune / acceptable? Le programme stocke déjà tellement mémoire je pensais que je commence à trouver des moyens de réduire la mémoire qu'il consomme.

Était-ce utile?

La solution

Bitfields (mais seulement si vous avez vraiment besoin d'être serré sur l'espace - les systèmes embarqués à savoir )?

typedef struct id_result {
    unsigned int id : 15;
    unsigned int result : 1;
} id_result;

sinon, oui, utiliser une struct avec des définitions plus complètes et significatives:

typedef uint16 IDTYPE; /* assuming uint16 exists elsewhere */

typedef struct id_result {
    IDTYPE id;
    bool result;
} id_result;

Autres conseils

À moins de mémoire est incroyablement serré, je vais la route struct. Il est beaucoup plus clair et plus facile de cette façon pour la prochaine personne qui doit maintenir votre code.

Je me rappelle l'époque où l'M68000 avait 32 registres d'adresses de bits mais seulement 24 bits d'entre eux ont été effectivement utilisés. Les programmeurs ont fait toutes sortes de « optimisations » pour stocker des informations dans les autres 8 bits. Boy étaient leurs visages rouge lorsque les versions ultérieures de la puce, comme le M68030, utilisé tous les 32 bits.

A moins qu'il n'y a absolument crise de la mémoire, je préfère aller approche plus simple d'avoir la structure à deux variables différentes. Il augmente la lisibilité et réduit les efforts de maintenance.

Si cela se fait uniquement dans le but de réduire l'utilisation de la mémoire, alors je crois que vous ne devriez pas le faire. Vous feriez mieux d'utiliser une structure avec 2 short qui rend le code beaucoup plus lisible. La quantité de mémoire que vous économisez en faisant très petit par rapport aux avantages que vous obtenez en faisant le code plus maintenable.

Je vous suggère de premier profil du système pour savoir s'il y a des fuites de mémoire ou si quelqu'un est inutilement gros morceaux alloue de la mémoire, etc., et puis essayer de résoudre ce problème. Si vous ne pouvez toujours pas trouver une solution, puis savoir quelle partie de votre programme prend la majeure partie de la mémoire et essayer de redessiner son modèle d'allocation de mémoire.

Pour ceux qui conseillent contre la conservation de la mémoire avec bitfields: les années passent et les ordinateurs deviennent plus gigaoctets, L1 $ (la mémoire rapide) reste juste quelques dizaines de kilo-octets. Pour la plupart des applications aujourd'hui, la majorité du temps est passé à attendre la mémoire lente pour arriver dans la L1 $.

Depuis la mémoire lente est le goulot d'étranglement dans la plupart des applications, la conservation de la mémoire avec bitfields peut effectivement augmenter de manière significative la vitesse d'une application. Ce ne fut pas aussi vrai il y a vingt ans.

Mise en place deux courts métrages en une seule courte vous est, à mon avis, plus de travail et plus sujettes à l'erreur que d'utiliser un struct. Si vous utilisez moins de mémoire est vraiment nécessaire, vous pouvez spécifier bitfields avec un struct:

struct myStruct {
int data:8;
int result:8;
};

On obtient le même résultat en réduisant la mémoire, tout en augmentant la maintenabilité globale du code.

Structs avec bitfields sont la mise en œuvre le plus compréhensible. Si vous n'utilisez pas cette approche, vous pouvez utiliser un ensemble de bien documenté macros Emballer et déballer la paire de valeurs dans et hors des valeurs 16 bits.

Utilisation / structs objets ne sont pas nécessairement la meilleure ou la plus claire approche.

Supposons que vous avez un ensemble de simples points de données entier, mais ils peuvent être supprimés ou marqués non valide, si vous utilisez simplement le MSB pour marquer comme « ne pas utiliser » tout ce que vous devez ajouter à l'algorithme est un

if ( item > 0 )
   item += blah

Mais si vous avez un struct alors tous les bits de arithmatic maintenant besoin d'un accès membre

if ( item.valid() ) 
   item.setValue(item.getValue() + blah);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top