Cluster member variables declaration by their type useful or not?

Please have a look a the following code sample, executed on a Windows-32 system using Visual Studio 2010:

#include <iostream>

using namespace std;

class LogicallyClustered
{
    bool _fA;
    int _nA;
    char _cA;

    bool _fB;
    int _nB;
    char _cB;
};

class TypeClustered
{
    bool _fA;
    bool _fB;

    char _cA;
    char _cB;

    int _nA;
    int _nB;
};

int main(int argc, char* argv[])
{
    cout << sizeof(LogicallyClustered) << endl; // 20
    cout << sizeof(TypeClustered) << endl; // 12

    return 0;
}

Question 1

The sizeof the two classes varies because the compiler is inserting padding bytes to achieve an optimized memory allignment of the variables. Is this correct?

Question 2

Why is the memory footprint smaller if I cluster the variables by type as in class TypeClustered ?

Question 3

Is it a good rule of thumb to always cluster member variables according to their type? Should I also sort them according to their size ascending (bool, char, int, double...)?

EDIT

Additional Question 4

A smaller memory footprint will improve data cache efficiency, since more objects can be cached and you avoid full memory accesses into "slow" RAM. So could the ordering and grouping of the member declaration can be considered as a (small) but easy to achieve performance optimization?


1) Absolutely correct.

2) It's not smaller because they are grouped, but because of the way they are ordered and grouped . For example, if you declare 4 chars one after the other, they can be packed into 4 byte. If you declare one char and immediately one int , 3 padding bytes will be inserted as the int will need to be aligned to 4 bytes.

3) No! You should group members in a class so that the class becomes more readable.

Important note: this is all platform/compiler specific. Don't take it ad-literam.

Another note - there also exist some small performance increase on some platforms for accessing members that reside in the first n (varies) bytes of a class instance. So declaring frequently accessed members at the beginning of a class can result in a small speed increase. However, this too shouldn't be a criteria. I'm just stating a fact, but in no way recommend you do this.


You are right, the size differs because the compiler inserts padding bytes in class LogicallyClustered. The compiler should use a memory layout like this:

class LogicallyClustered 
{ 
    // class starts well aligned
    bool _fA;
    // 3 bytes padding (int needs to be aligned)
    int _nA; 
    char _cA; 

    bool _fB; 
    // 2 bytes padding (int needs to be aligned)
    int _nB; 
    char _cB; 
    // 3 bytes padding (so next class object in an array would be aligned)
}; 

Your class TypeClustered does not need any padding bytes because all elements are aligned. bool and char do not need alignment, int needs to be aligned on 4 byte boundary.

Regarding question 3 I would say (as often :-)) "It depends.". If you are in an environment where memory footprint does not matter very much I would rather sort logically to make the code more readable. If you are in an environment where every byte counts you might consider moving around the members for optimal usage of space.


除非没有严重的内存占用情况限制,否则将它们逻辑集群化,这可以提高代码的可读性并易于维护。

链接地址: http://www.djcxy.com/p/29808.html

上一篇: 使用long int避免溢出是一种很好的做法吗?

下一篇: 集群成员变量声明的类型是否有用?