前些天看到有评论说标准库的string占内存大,效率低,而且函数不实用。而我正在写一个大量处理字符串的程序,所以不得不自己测试一下了。看看是继续用STL库还是回头再用MFC或者干脆不用库函数了。
环境:XP Professional 2002 SP3
Microsoft Visual C++ 6.0
Project Settings:首先都采用Win32ConsoleApplication empty project的初始选项
作如下修改,
link:删除/subsystem 开关,其余不变。
C/C++(Code Generation):Use Runtime Library:Debug MultiThread
General:Not Using MFC(虽然我实际上用了,这里不选)
Language:英语(美国)
当然,免费的VC++6.0,不能采用Release编译连接,只好用Debug了。
一。文件大小
CString:
/************************* test.h **************************/ #include <afx.h>//afx.h包含windows.h,于是,就少了#include <windows.h> /************************* test.cpp **************************/ #include "test.h" int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lpCmdLine,int nShowCmd) { CString s="Hello World!"; return 0; }
Compile:
test.obj 6.50KB
CString.pdb 2249KB
CString.ilk 1654KB
link:
CString.exe 1.25MB
STLstring:
/********************** test.h ***********************/ #include <windows.h> #include <string> /********************** test.cpp ***********************/ int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lpCmdLine,int nShowCmd) { string s; s.assign("Hello World!"); return 0; }
Compile:
test.obj 31KB
STLstring.pdb 577KB
STLstring.ilk 304KB
link:
STLstring.exe 236KB
这么看来,就生成的可执行文件大小来说,用STL时小很多。
其实从pdb文件大小就看出来了:CString 所要求的动态链接库比STL string大太多了。
二。执行效率
CString:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lpCmdLine,int nShowCmd) { char* buf; buf=new char[128]; CString s; DWORD start,end; start=::timeGetTime(); for(DWORD i=0;i<10000000;i++) { s=";riusvnaervCs;eriv"; s.Find("C",0); } end=::timeGetTime(); ::itoa(end-start,buf,10); MessageBox(::GetActiveWindow(),buf,"CString",MB_OK); delete []buf; return 0; }
STLstring:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lpCmdLine,int nShowCmd) { char* buf; buf=new char[128]; string s; DWORD start,end; start=::timeGetTime(); for(DWORD i=0;i<10000000;i++) { s=";riusvnaervCs;eriv"; s.find("C",0); } end=::timeGetTime(); ::itoa(end-start,buf,10); MessageBox(::GetActiveWindow(),buf,"STLstring",MB_OK); delete []buf; return 0; }
执行结果:
多次执行,记录如下:
CString :5258 5117 5195 5204 5184
STLstring:4833 4745 4758 4746 4749
显示的数字是循环开始前到循环结束经过的时间(毫秒)。
我们再来看另一个实验:
CString:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lpCmdLine,int nShowCmd) { char* buf; buf=new char[128]; CString s="CCCCCCCCCC"; DWORD start,end; start=::timeGetTime(); for(DWORD i=0;i<10000000;i++) { s=s.Mid(1); s+='C'; } end=::timeGetTime(); ::itoa(end-start,buf,10); MessageBox(::GetActiveWindow(),buf,"CString",MB_OK); delete []buf; return 0; }
STLstring:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lpCmdLine,int nShowCmd) { char* buf; buf=new char[128]; string s="CCCCCCCCCC"; DWORD start,end; start=::timeGetTime(); for(DWORD i=0;i<10000000;i++) { s=s.substr(1); s+='C'; } end=::timeGetTime(); ::itoa(end-start,buf,10); MessageBox(::GetActiveWindow(),buf,"STLstring",MB_OK); delete []buf; return 0; }
运行结果:
STL比MFC的字符串对象稍稍快那么一点。
内存上呢?
就用上面的实验,循环中:
循环结束至出现提示框:
OK,测试内存占用,我没什么招数,只好用任务管理器了。但是,CString和STL的string的差异也被我发现了。
没什么好说的了。
CString 除了用起来比较方便,(我最喜欢的就是它的Replace函数可以消灭掉字符串中的所有指定文本,
比如对 CString str="He is doing something,something interesting,something that I don't know." ;
使用 str.Replace("th","");
结果就会消除掉 str中的所有 "th",用起来就像 php一样方便。可惜在STL里面没有这样的函数。)
CString除了比STL多点实用的函数,其他方面还是不能和标准库相比的。
最可恶的就是,一句 #include <afx.h>,就能使可执行文件从数百 KB 一跃至数 MB ,增大6、7倍。
恐怕,今后我会不用MFC了。
Windows编程,老老实实地用SDK吧。