- 2012-2-24
- Visual C++
仕事でCMapとCStringArrayどっちが早いのかという状況になって、シーケンシャルアクセスする状況では
CMapよりもCStringArrayのほうが速いのでは?ということになり、検証してみた。
各処理を100万回実行。
class Test
{
public:
char aaa[256];
Test(){}
};
class Test2
{
public:
CString aaa;
Test2(){}
};
typedef struct _STRACT
{
char str[256];
}STRACT;
int _tmain(int argc, _TCHAR* argv[])
{
int ii = 0;
CString str;
long t = 0;
CMap<UINT,UINT,CString,CString> map;
CStringArray Freearr;
char ch[256] = {NULL};
//---------------------------------------------------
// CMap
//---------------------------------------------------
//set CMap
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
map[ii] = "str";
}
t = GetTickCount() -t;
sprintf(ch,"CMap set 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//get CMap
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
str = map[ii];
}
t = GetTickCount() -t;
sprintf(ch,"CMap get 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//---------------------------------------------------
// CStringArray サイズ未設定
//---------------------------------------------------
//set CStringArray
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
Freearr.Add("str");
}
t = GetTickCount() -t;
sprintf(ch,"CStringArray::Add 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//get CMap
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
str = Freearr.GetAt(ii);
}
t = GetTickCount() -t;
sprintf(ch,"CStringArray::GetAt 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//---------------------------------------------------
// CStringArray サイズ設定
//---------------------------------------------------
CStringArray FixedArr;
//set CStringArray
t = GetTickCount();
FixedArr.SetSize(1000000); //サイズがわかっているとしたら
t = GetTickCount() -t;
sprintf(ch,"CStringArray(固定) SetSize 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
FixedArr.SetAt(ii,"str");
}
t = GetTickCount() -t;
sprintf(ch,"CStringArray(固定)::SetAt 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//get CMap
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
str = FixedArr.GetAt(ii);
}
t = GetTickCount() -t;
sprintf(ch,"CStringArray(固定)::GetAt 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//---------------------------------------------------
// Testクラス サイズ未設定
//---------------------------------------------------
Test* clsT = NULL;
t = GetTickCount();
clsT = new Test[1000000];
t = GetTickCount() -t;
sprintf(ch,"Testクラス new1000000 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//set Test
t = GetTickCount(); for( ii = 0; ii < 1000000 ; ii++ )
{
memset( clsT[ii].aaa,0,sizeof(clsT[ii].aaa) );
memcpy( clsT[ii].aaa,"str",3);
}
t = GetTickCount() -t;
sprintf(ch,"Testクラス set 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//get CMap
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
str = clsT[ii].aaa;
}
t = GetTickCount() -t;
sprintf(ch,"Testクラス get 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
t = GetTickCount();
delete [] clsT;
t = GetTickCount() -t;
sprintf(ch,"Testクラス delete 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//---------------------------------------------------
// Test2クラス サイズ未設定
//---------------------------------------------------
Test2* clsT2 = NULL;
t = GetTickCount();
clsT2 = new Test2[1000000];
t = GetTickCount() -t;
sprintf(ch,"Test2クラス(メンバ:CString) new1000000 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//set Test
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
clsT2[ii].aaa="str";
}
t = GetTickCount() -t;
sprintf(ch,"Test2クラス(メンバ:CString) set 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//get CMap
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
str = clsT2[ii].aaa;
}
t = GetTickCount() -t;
sprintf(ch,"Test2クラス(メンバ:CString) get 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
t = GetTickCount();
delete [] clsT2;
t = GetTickCount() -t;
sprintf(ch,"Test2クラス(メンバ:CString) delete 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//---------------------------------------------------
// 構造体 サイズ未設定
//---------------------------------------------------
STRACT* st = NULL;
t = GetTickCount();
st = new STRACT[1000000];
t = GetTickCount() -t;
sprintf(ch,"構造体 new1000000 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//set Test
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
memset( st[ii].str,0,sizeof(st[ii].str) );
memcpy( st[ii].str,"str",3);
}
t = GetTickCount() -t;
sprintf(ch,"構造体 set 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
//get CMap
t = GetTickCount();
for( ii = 0; ii < 1000000 ; ii++ )
{
str = st[ii].str;
}
t = GetTickCount() -t;
sprintf(ch,"構造体 get 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
t = GetTickCount();
delete [] st;
t = GetTickCount() -t;
sprintf(ch,"構造体 delete 処理時間[%ld]ミリ秒\r\n",t);
printf("%s",ch);
_getch();
return 0;
}
結果:
CMap set 処理時間[131665]ミリ秒
CMap get 処理時間[128747]ミリ秒
CStringArray::Add 処理時間[2543]ミリ秒
CStringArray::GetAt 処理時間[63]ミリ秒
CStringArray(固定) SetSize 処理時間[31]ミリ秒
CStringArray(固定)::SetAt 処理時間[483]ミリ秒
CStringArray(固定)::GetAt 処理時間[63]ミリ秒
Testクラス new1000000 処理時間[0]ミリ秒
Testクラス set 処理時間[265]ミリ秒
Testクラス get 処理時間[234]ミリ秒
Testクラス delete 処理時間[16]ミリ秒
Test2クラス(メンバ:CString) new1000000 処理時間[46]ミリ秒
Test2クラス(メンバ:CString) set 処理時間[375]ミリ秒
Test2クラス(メンバ:CString) get 処理時間[62]ミリ秒
Test2クラス(メンバ:CString) delete 処理時間[94]ミリ秒
構造体 new1000000 処理時間[0]ミリ秒
構造体 set 処理時間[203]ミリ秒
構造体 get 処理時間[218]ミリ秒
構造体 delete 処理時間[31]ミリ秒
(デバッグモードではもうちょい遅いので、計測するならちゃんとexe作ってexeを実行すること)
結論として、シーケンシャルアクセスするんだったらCMapよりもCStringArrayの方が速い。 CMapの利点はダイレクトアクセスであって、シーケンシャルアクセスには向いていない。 で、件数があらかじめわかってるなら、CStringArray::Addよりも SetSize ⇒ SetAt の方が早い。 もっというなら、やっぱりネイティブに作った方が早い。









