I did a test,the result shows that they are nearly identical in efficiency,both 32bits and 64bits,here is my test code
union UValue
{
void SetVal2(int val);
int GetVal2(void);
struct
{
char m_nVal1;
char m_nVal3;
short m_nVal2;
};
int m_nVal;
} uValue;
void UValue::SetVal2(int val)
{
m_nVal = (m_nVal & 65535) | (val << 16);
}
int UValue::GetVal2(void)
{
return m_nVal >> 16;
}
#define nCount (1024 * 1024 * 128)
UValue arUVal[nCount];
unsigned int nSum;
int main(void)
{
cout << sizeof(UValue) << endl;
int n = arUVal[0].GetVal2();
LARGE_INTEGER frequency; // ticks per second
LARGE_INTEGER t1, t2; // ticks
double elapsedTime;
srand(time(NULL));
QueryPerformanceFrequency(&frequency);
//----------------------------------------------------------------------------------------------------
QueryPerformanceCounter(&t1);
for (unsigned int i = 0; i < nCount; ++i)
{
arUVal.m_nVal2 = rand();
}
for (unsigned int i = 1; i < nCount; ++i)
{
arUVal.m_nVal2 = arUVal.m_nVal2 + 1;
}
for (unsigned int i = 1; i < nCount; ++i)
{
nSum += arUVal.m_nVal2;
}
QueryPerformanceCounter(&t2);
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
cout << "sum of direct access: " << nSum << " milliseconds used: " <<elapsedTime<<endl;
//----------------------------------------------------------------------------------------------------
QueryPerformanceCounter(&t1);
for (unsigned int i = 0; i < nCount; ++i)
{
arUVal.SetVal2(rand());
}
for (unsigned int i = 1; i < nCount; ++i)
{
arUVal.SetVal2(arUVal.GetVal2() + 1);
}
for (unsigned int i = 1; i < nCount; ++i)
{
nSum += arUVal.GetVal2();
}
QueryPerformanceCounter(&t2);
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
cout << "sum of function access: " << nSum << " milliseconds used: " << elapsedTime << endl;
}
And the order of these two code blocks matters,who comes latter who is slightly faster.And the result is the same even i changed the union to this
#pragma pack(1)
union UValue
{
void SetVal2(int val);
int GetVal2(void);
struct
{
char m_nVal1;
short m_nVal2;
char m_nVal3;
};
int m_nVal;
} uValue;