|
楼主 |
发表于 2015-6-5 12:00:34
|
显示全部楼层
在 #2 楼的启迪下测试了 bitset 类(以前居然不知道,汗...),感觉执行效率和直接数组还是很接近的。
【测试方法】
1. 生成一个长比特串,使用字节数组存储,每个单元只用1位;
2. 向比特串的随机位置填入规定好的帧头(实际情况下,步骤1、2生成的数据被压缩在收到的字节中)
3. 分别使用 bitset、CString 方法查找帧头,累加步骤 3 的查找时间
4. 步骤 1-3 循环 10000 遍,输出结果
【测试环境】
PC:三星 S3440VC
CPU:i5-3210M @ 2.50GHz
RAM:4.00GB
OS:Win8.1 (64bit)
IDE:VS2005
【测试代码】
- // test.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include "test.h"
- #include "bitset"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- // 唯一的应用程序对象
- CWinApp theApp;
- using namespace std;
- #define USE_STATIC_MEM
- int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
- {
- int nRetCode = 0;
- // 初始化 MFC 并在失败时显示错误
- if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
- {
- // TODO: 更改错误代码以符合您的需要
- _tprintf(_T("错误: MFC 初始化失败\n"));
- return 1;
- }
- BYTE bufData[8192];
- const BYTE bufStart[24]=
- {
- 1,0,1,0,0,0,1,0,
- 0,1,0,0,1,1,0,0,
- 0,0,1,0,1,0,0,1,
- };
- LARGE_INTEGER liFreq, liSt, liEd;
- ::QueryPerformanceFrequency(&liFreq);
- // #1: CString
- int nOk1= 0; // 标记成功个数
- LONGLONG nTm1= 0; // 记录累计时间
- DWORD nSum1= 0; // 所有成功位置校验和
- srand(0x5a78);
- for(int i=0; i<10000; i++)
- {
- // 生成原始数据(0/1)
- ZeroMemory(bufData, sizeof(bufData));
- int ibufStart= rand()%(_countof(bufData)-_countof(bufStart));
- memcpy(bufData+ibufStart, bufStart, sizeof(bufStart));
- ::QueryPerformanceCounter(&liSt);
- // 生成字串及模板
- #ifdef USE_STATIC_MEM
- static CString szCode, szStart;
- #else
- CString szCode, szStart;
- #endif
- TCHAR * pstr;
- pstr= szCode.GetBufferSetLength(_countof(bufData));
- for(int i=0; i<_countof(bufData); i++)
- {
- pstr[i]= bufData[i]? _T('1'):_T('0');
- }
- szCode.ReleaseBuffer();
- pstr= szStart.GetBufferSetLength(_countof(bufStart));
- for(int i=0; i<_countof(bufStart); i++)
- {
- pstr[i]= bufStart[i]? _T('1'):_T('0');
- }
- szStart.ReleaseBuffer();
- // 查找起始
- int rst= szCode.Find(szStart);
- if(rst>=0)
- {
- nOk1++;
- nSum1+= rst;
- }
- ::QueryPerformanceCounter(&liEd);
- nTm1+= liEd.QuadPart - liSt.QuadPart;
- }
- // #2: Bitset
- int nOk2= 0; // 标记成功个数
- LONGLONG nTm2= 0; // 记录累计时间
- DWORD nSum2= 0; // 所有成功位置校验和
- srand(0x5a78);
- for(int i=0; i<10000; i++)
- {
- // 生成原始数据(0/1)
- ZeroMemory(bufData, sizeof(bufData));
- int ibufStart= rand()%(_countof(bufData)-_countof(bufStart));
- memcpy(bufData+ibufStart, bufStart, sizeof(bufStart));
- ::QueryPerformanceCounter(&liSt);
- // 生成操作类模板
- #ifdef USE_STATIC_MEM
- static bitset<_countof(bufData)> bsCode;
- #else
- bitset<_countof(bufData)> bsCode;
- #endif
- for(int i=0; i<_countof(bufData); i++)
- {
- bsCode[i]= bufData[i]? TRUE:FALSE;
- }
- // 查找起始
- int rst, sch;
- for(rst=0; rst<_countof(bufData); rst++)
- {
- for(sch=0; sch<_countof(bufStart); sch++)
- {
- if(rst+sch>=_countof(bufData))
- {
- break;
- }
- if(bsCode[rst+sch] != (bufStart[sch]?TRUE:FALSE))
- {
- break;
- }
- }
- if(sch>=_countof(bufStart))
- {
- break;
- }
- }
- if(rst<_countof(bufData))
- {
- nOk2++;
- nSum2+= rst;
- }
- ::QueryPerformanceCounter(&liEd);
- nTm2+= liEd.QuadPart - liSt.QuadPart;
- }
- #ifdef USE_STATIC_MEM
- printf("(static memory mode)\n\n");
- #else
- printf("(non-static memory mode)\n\n");
- #endif
- printf("Method #1(CString):\n");
- printf("Chksum= %08X, Time=%lf ms\n", nSum1, nTm1/(liFreq.QuadPart/1e3));
- printf("\n");
- printf("Method #2(bitset):\n");
- printf("Chksum= %08X, Time=%lf ms\n", nSum2, nTm2/(liFreq.QuadPart/1e3));
- printf("\n");
- system("pause");
- return nRetCode;
- }
复制代码
附上测试项目包:
【测试结果】
分别使用了非静态局部、静态局部的核心工作类,结果截图如下:
【测试结论】
bitset、CString 执行速度相近,基本上只要不频繁申请内存,速度都差不多。
由此也大致能推测出 bitset 使用了类似数组的 CPU 寻址结构,相较于直接移位操作应该有所优化。
但由于未评估内存消耗的数量,故此留作后日慢慢测试。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|