测试效率需要计时的模块
所以首先发一下计时模块的代码,用的是QueryPerformanceFrequency跟QueryPerformanceCounter
CPerformance.h头文件
#ifndef _CPerformance_h_
#define _CPerformance_h_
#include <windows.h>
class CPerformance
{
public:
CPerformance();
~CPerformance();
void Start();
float End();//返回距离上一次Start()所经历的毫秒数
private:
LARGE_INTEGER m_dwFrequency;
LARGE_INTEGER m_dwQPart1;
LARGE_INTEGER m_dwQPart2;
};
#endif
cpp
#include "CPerformance.h"
CPerformance::CPerformance()
{
m_dwQPart1.QuadPart = 0;
m_dwQPart2.QuadPart = 0;
m_dwFrequency.QuadPart = 0;
QueryPerformanceFrequency(&m_dwFrequency);
}
CPerformance::~CPerformance()
{
}
void CPerformance::Start()
{
QueryPerformanceCounter(&m_dwQPart1);
}
float CPerformance::End()
{
QueryPerformanceCounter(&m_dwQPart2);
float fTime = (m_dwQPart2.QuadPart - m_dwQPart1.QuadPart) * 1000.0f / m_dwFrequency.QuadPart;
return fTime;
}
下面是测试过程
测试环境:
系统是XP的SP3
cpu是AMD Athlon(tm) II X4 640 3.01GHz
内存2.75G
IDE是VS2005
测试程序是release版本,优化开最大速度(Optimization=Maximize Speed (/O2))
下面是之前实现的AVL树(TTree)与stl的map和set的对比测试结果:
测试代码
CPerformance perf;
float fTime = 0.0f;
srand(time(NULL));
TLeaf<DWORD, DWORD> *pLeaf = new TLeaf<DWORD, DWORD>[1000000];
for (DWORD i = 0; i < 1000000; i++)
{
pLeaf[i].Init();
pLeaf[i].m_Key = i;
pLeaf[i].m_Value = i;
}
TTree<DWORD, DWORD> tree;
tree.Init(enum_DisableLock_Tree);
std::map<DWORD, DWORD> stlmap;
std::set<DWORD> stlset;
//打乱顺序
for (DWORD i = 0; i < 1000000; i++)
{
DWORD j = rand() % 1000 * 1000 + rand() % 1000;
DWORD temp = pLeaf[i].m_Value;
pLeaf[i].m_Value = pLeaf[j].m_Value;
pLeaf[j].m_Value = temp;
pLeaf[i].m_Key = pLeaf[i].m_Value;
pLeaf[j].m_Key = pLeaf[j].m_Value;
}
//TTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
tree.Insert(pLeaf + i);
}
fTime = perf.End();
printf("TTree Insert %f\n", fTime);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
tree.Find(pLeaf[i].m_Key);
}
fTime = perf.End();
printf("TTree Find %f\n", fTime);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
tree.Remove(pLeaf[i].m_Key);
}
fTime = perf.End();
printf("TTree Remove %f\n\n", fTime);
//map>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
stlmap.insert(std::map<DWORD, DWORD>::value_type(pLeaf[i].m_Key, pLeaf[i].m_Value));
}
fTime = perf.End();
printf("map insert %f\n", fTime);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
stlmap.find(pLeaf[i].m_Key);
}
fTime = perf.End();
printf("map find %f\n", fTime);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
stlmap.erase(pLeaf[i].m_Key);
}
fTime = perf.End();
printf("map erase %f\n\n", fTime);
//set>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
stlset.insert(pLeaf[i].m_Value);
}
fTime = perf.End();
printf("set insert %f\n", fTime);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
stlset.find(pLeaf[i].m_Value);
}
fTime = perf.End();
printf("set find %f\n", fTime);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
stlset.erase(pLeaf[i].m_Value);
}
fTime = perf.End();
printf("set erase %f\n\n", fTime);
if (NULL != pLeaf)
{
delete[] pLeaf;
}
测试结果(单位毫秒)
100W数据量,TTree的插入跟删除由于没有分配内存的消耗,因此跟stl的可比性不大。
查找这个功能不涉及内存分配,比较下来是比stl要快的。
双链表的测试代码
CPerformance perf;
float fTime = 0.0f;
srand(time(NULL));
TBDLinker<DWORD> *pLinker = new TBDLinker<DWORD>[1000000];
for (DWORD i = 0; i < 1000000; i++)
{
pLinker[i].m_Value = i;
}
for (DWORD i = 0; i < 1000000; i++)//随机打乱顺序
{
DWORD j = rand() % 1000 * 1000 + rand() % 1000;
DWORD temp = pLinker[i].m_Value;
pLinker[i].m_Value = pLinker[j].m_Value;
pLinker[j].m_Value = temp;
}
TBDLinkList<DWORD> linklist;
linklist.Init(enum_DisableLock_BDLink);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
linklist.PushTail(pLinker + i);
}
fTime = perf.End();
printf("TBDLinkList PushTail %f\n", fTime);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
linklist.PopHead();
}
fTime = perf.End();
printf("TBDLinkList PopHead %f\n\n", fTime);
std::list<DWORD> stllist;
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
stllist.push_back(pLinker[i].m_Value);
}
fTime = perf.End();
printf("list push_back %f\n", fTime);
perf.Start();
for (DWORD i = 0; i < 1000000; i++)
{
stllist.pop_front();
}
fTime = perf.End();
printf("list pop_front %f\n\n", fTime);
测试结果(单位毫秒)
list慢很多,不知道是不是我测试代码有问题。。。
本文通过自定义计时模块对比了自定义AVL树(TTree)与STL中的map和set, 以及自定义双链表(TBDLinkList)与STL中list的性能。测试结果显示,在查找操作上自定义AVL树表现优于STL, 而对于双链表的插入和弹出操作,自定义实现也显著优于STL。
2020

被折叠的 条评论
为什么被折叠?



