流数据解析中高位地址转换的性能分析
在流数据(文件、网络)解析中,常常碰到低位高址与低位低址的转换问题,心血来潮,分析了一下各种转换方法的性能。
废话少说,直接上代码:
#include "windows.h"
inline DWORD SwapDWORD_0(DWORD in)
{
return (in << 24) | ((in & 0x0000FF00) << 8) | ((in & 0x00FF0000) >> 8) | (in >> 24);
}
inline DWORD SwapDWORD_1(DWORD in)
{
BYTE* pb = (BYTE*)(&in);
BYTE temp;
temp = pb[0]; pb[0] = pb[3]; pb[3] = temp;
temp = pb[1]; pb[1] = pb[2]; pb[2] = temp;
return in;
}
inline DWORD SwapDWORD_2(DWORD in)
{
BYTE* pb = (BYTE*)(&in);
BYTE temp;
for(int i = 0, j = 3; i < j; ++i,--j){
temp = pb[i]; pb[i] = pb[j]; pb[j] = temp;
}
return in;
}
inline DWORD SwapDWORD_3(DWORD in)
{
DWORD out;
BYTE* pin = (BYTE*)(&in);
BYTE* pout = (BYTE*)(&out);
pout[0] = pin[3];
pout[1] = pin[2];
pout[2] = pin[1];
pout[3] = pin[0];
return out;
}
inline DWORD SwapDWORD_4(DWORD in)
{
DWORD out;
BYTE* pin = (BYTE*)(&in);
BYTE* pout = (BYTE*)(&out);
for(int i = 0; i < 4; ++i){
pout[i] = pin[3-i];
}
return out;
}
///////////////////////////////////////////////////////////////////////////////////////
inline void SwapDWORD_R0(DWORD& in)
{
in = (in << 24) | ((in & 0x0000FF00) << 8) | ((in & 0x00FF0000) >> 8) | (in >> 24);
}
inline void SwapDWORD_R1(DWORD& in)
{
BYTE* pb = (BYTE*)(&in);
BYTE temp;
temp = pb[0]; pb[0] = pb[3]; pb[3] = temp;
temp = pb[1]; pb[1] = pb[2]; pb[2] = temp;
}
inline void SwapDWORD_R2(DWORD& in)
{
BYTE* pb = (BYTE*)(&in);
BYTE temp;
for(int i = 0, j = 3; i < j; ++i,--j){
temp = pb[i]; pb[i] = pb[j]; pb[j] = temp;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int loopCount = 10000000;
int i;
DWORD start, end;
DWORD dw;
dw = 0x01020304;
start = ::GetTickCount();
for(i = 0; i < loopCount; i ++){
dw = SwapDWORD_0(dw);
}
end = ::GetTickCount();
printf("SwapDWORD_0 takes: %d - 0x%08x\n", end - start, dw);
dw = 0x11223344;
start = ::GetTickCount();
for(i = 0; i < loopCount; i ++){
dw = SwapDWORD_1(dw);
}
end = ::GetTickCount();
printf("SwapDWORD_1 takes: %d - 0x%08x\n", end - start, dw);
dw = 0xaa223344;
start = ::GetTickCount();
for(i = 0; i < loopCount; i ++){
dw = SwapDWORD_2(dw);
}
end = ::GetTickCount();
printf("SwapDWORD_2 takes: %d - 0x%08x\n", end - start, dw);
dw = 0x1122bb44;
start = ::GetTickCount();
for(i = 0; i < loopCount; i ++){
dw = SwapDWORD_3(dw);
}
end = ::GetTickCount();
printf("SwapDWORD_3 takes: %d - 0x%08x\n", end - start, dw);
dw = 0xEE223344;
start = ::GetTickCount();
for(i = 0; i < loopCount; i ++){
dw = SwapDWORD_4(dw);
}
end = ::GetTickCount();
printf("SwapDWORD_4 takes: %d - 0x%08x\n", end - start, dw);
printf("----------------------------------------------\n");
start = ::GetTickCount();
for(i = 0; i < loopCount; i ++){
SwapDWORD_R0(dw);
}
end = ::GetTickCount();
printf("SwapDWORD_R0 takes: %d - 0x%08x\n", end - start, dw);
dw = 0x11223344;
start = ::GetTickCount();
for(i = 0; i < loopCount; i ++){
SwapDWORD_R1(dw);
}
end = ::GetTickCount();
printf("SwapDWORD_R1 takes: %d - 0x%08x\n", end - start, dw);
dw = 0xaa223344;
start = ::GetTickCount();
for(i = 0; i < loopCount; i ++){
SwapDWORD_R2(dw);
}
end = ::GetTickCount();
printf("SwapDWORD_R2 takes: %d - 0x%08x\n", end - start, dw);
return 0;
}
运行结果:
SwapDWORD_0 takes: 47ms - 0x01020304
SwapDWORD_1 takes: 218ms - 0x11223344
SwapDWORD_2 takes: 234ms - 0xaa223344
SwapDWORD_3 takes: 203ms - 0x1122bb44
SwapDWORD_4 takes: 203ms - 0xee223344
-----------------------------------
SwapDWORD_R0 takes: 62ms - 0xee223344
SwapDWORD_R1 takes: 16ms - 0x11223344
SwapDWORD_R2 takes: 47ms - 0xaa223344
结论:
对于原址转换,SwapDWORD_R1最快,对于转换到其他变量里的,位操作最快。