메모리 비교 함수..
ANSI: memcpy()
VCL: CompareMem()
여기에 두가지 함수를 더 만들었습니다. 하나는 제가, 하나는 같이 일하는
친구가.
bool __fastcall CompareMemory1(void* Ref1, void* Ref2, int Length)
{
if(Length <= 0)
return true;
int nSize = Length / sizeof(int);
int* pIRef1 = (int*)Ref1;
int* pIRef2 = (int*)Ref2;
for (int ii = 0; ii < nSize; ii++)
{
if (pIRef1[ii] != pIRef2[ii])
return false;
}
nSize = Length - nSize * sizeof(int);
char *pCRef1 = (char*)Ref1;
char *pCRef2 = (char*)Ref2;
for (int ii = 0; ii < nSize; ii++)
{
if (pCRef1[ii] != pCRef2[ii])
return false;
}
return true;
}
//---------------------------------------------------------------------------
bool __fastcall CompareMemory2(void * Ref1, void * Ref2, int Length)
{
if(Length <= 0)
return true;
int * p1 = (int *)Ref1;
int * p2 = (int *)Ref2;
int remain = Length / sizeof(int);
int nByte = Length % sizeof(int);
for(int i = 0; i < remain; i++)
{
if(*p1 != *p2)
return false;
p1++;
p2++;
}
if(nByte)
{
nByte = 4 - nByte;
if(*p1 >> (nByte * 8) != *p2 >> (nByte * 8))
return false;
}
return true;
}
//---------------------------------------------------------------------------
그리고 가장 느릴꺼 뻔히 알지만 바이트단위의 비교를 위한 함수를 만들었습니다.
bool __fastcall CompareMemoryByChar(void* Ref1, void* Ref2, int Length)
{
if(Length <= 0)
return true;
unsigned char *pCRef1 = (unsigned char*)Ref1;
unsigned char *pCRef2 = (unsigned char*)Ref2;
for (int ii = 0; ii < Length; ii++)
{
if (pCRef1[ii] != pCRef2[ii])
return false;
}
return true;
}
한 번 심심해서 테스트해 봤더니.. 결과가 어떻게 나왔을까요?
결론부터 말하자면, memcmp가 가장 느립니다.
Debug모드에서는 VCL의 CompareMem이 가장 빠르고, Release모드에서도 속도가 변함이 없습니다.
그러나 직접 만든 것이 릴리즈모드에서는 더 빠릅니다.
테스트는 97MB짜리 야동을 메모리에 적재해서 수행했습니다.
일단, 디버깅모드에서의 테스트 결과입니다.
속도순서입니다.
CompareMem(): Same!! 681
CompareMemory2(): Same!! 841
CompareMemory1(): Same!! 912
memcmp(): Same!! 921
CompareMemoryByChar(): Same!! 2022
릴리즈모드에서의 테스트 결과입니다. (80386으로 설정)
CompareMemory2(): Same!! 681
CompareMemory1(): Same!! 701
CompareMem(): Same!! 731
memcmp(): Same!! 951
CompareMemoryByChar(): Same!! 1142
릴리즈모드에서의 테스트 결과입니다. (i486으로 설정)
CompareMemory2(): Same!! 671
CompareMemory1(): Same!! 691
CompareMem(): Same!! 711
memcmp(): Same!! 921
CompareMemoryByChar(): Same!! 1132
릴리즈모드에서의 테스트 결과입니다. (Pentium으로 설정)
CompareMemory2(): Same!! 671
CompareMemory1(): Same!! 691
CompareMem(): Same!! 701
memcmp(): Same!! 922
CompareMemoryByChar(): Same!! 1131
릴리즈모드에서의 테스트 결과입니다. (Pentium Pro로 설정)
CompareMemory2(): Same!! 671
CompareMem(): Same!! 691
CompareMemory1(): Same!! 691
memcmp(): Same!! 931
CompareMemoryByChar(): Same!! 1122
디버깅 모드에서는 단연 어셈으로 만들어진 VCL의 CompareMem() 함수가 가장 빨랐지만
릴리즈모드에서는 결과가 뒤집혀지는군요.
제가 보기좋게 만들어 놓은거랑 속도가 비슷하고, 옆 친구가 맨처음에 꼴찌해서 열받
아서 새로 만든 CompareMemory2가 속도가 가장 빠릅니다.
맨 처음에 디버깅모드에서 테스트한 결과만으로 게시물을 올렸다가 다시 수정했습니다.
릴리즈모드에서는 얘기가 많이 달라지네요. CompareMem은 어셈이라서 디버깅이나 릴리
즈나 속도 차이가 없는게 장점이지만 최고의 성능은 아니고..
ANSI의 memcmp는 쓰지 말아야 겠다는 생각입니다. 물론 다른 컴파일러에서의 성능은
어떨지 모르겠지만.
사실 메모리 비교는 자주 쓰이지는 않지만, 이런 함수를 찾게 될 때는 보통 몇 ms가
성능에 크게 영향을 줄 때겠죠. 참고하세요.
|