Bonsoir ^_^,
Je ne savais pas où mettre ce message, j'ai hésité avec la rubrique "Contribuez", mais ce n'est pas vraiment de moi =). J'ai trouvé cette astuce sur un blog et je vous la partage car je la trouve très utile. Par contre, elle ne fonctionne que sous Visual.
Vous n'êtes sûrement pas sans savoir que, afin de minimiser l'espace mémoire, les variables membres d'une classe ou d'une structure doivent être organisées suivant un ordre précis afin d'éviter de créer des "paddings" inutiles. J'imagine que le compilateur est suffisamment intelligent pour pouvoir réorganiser lui-même les variables (quelqu'un pourrait confirmer ou infirmer ?), mais c'est toujours mieux de le faire soi-même.
Concrètement, voici une structure qui illustre ce soucis :
Puisque l'alignement se fait sur 4 octets, le compilateur va donc automatiquement ajouter un padding de 3 octets entre la variable a et b, et 3 autres entre c et d, ce qui donnera en fait ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 struct Test { char a; // 1 octet int b; // 4 octets char c; // 1 octet int d; // 4 octets };
On a donc, dans cette structure, 6 octets qui sont gâchés. Il est parfois assez chiant de devoir compter soi-même pour réorganiser les données, et en fait, il existe un warning à activer qui permet de lever un warning automatiquement pour indiquer ça. C'est bizarre car même avec le warning niveau 4 il n'est pas activé.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 struct Test { char a; // 1 octet char pad[3]; // 3 octets int b; // 4 octets char c; // 1 octet char pad2[3]; // 3 octets int d; // 3 octets };
L'astuce consiste en encadrer la structure par #pragma warning(error: 4820) et #pragma warning(disable: 4820), ce qui donne :
Et le compilateur lève le warning suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 #pragma warning(error: 4820) struct Test { char a; // 1 octet int b; // 4 octets char c; // 1 octet int d; // 4 octets }; #pragma warning(disable: 4820)
'Test' : '3' bytes padding added after data member 'Test::a'
'Test' : '3' bytes padding added after data member 'Test::c'
On sait donc immédiatement ou le padding est ajouté, et on peut donc réorganiser la structure comme ceci :
Et hop ! Au lieu de perdre 6 octets sur la structure on n'en perd que deux =). Je sais très bien que c'est le genre de micro-optimisation qui ne va pas changer grand chose en terme de performances, mais c'est tellement simple à réorganiser que je vois pas pourquoi on s'en priverait On peut ensuite enlever les #pragma et aller tester une autre classe.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 struct Test { int b; // 4 octets int d; // 4 octets char a; // 1 octet char c; // 1 octet char pad[2]; // 2 octets };
Partager