今天给大家推荐一个VC6.0当中好玩又实用的功能,配置文件(Profiling)。这个功能是用来对che进行性能优化的,它可以实现对程序的行覆盖率(line coverage)和函数覆盖率(function coverage)的测试,由此来找出程序在运行时的性能瓶颈点。不过在我看来,用这个功能来做一下小规模的白盒测试也是个很不错的主意,虽然VC的工程师们不推荐那样做,呵呵。
要启动配置文件(Profiling)功能,首先要保证你所使用的VC6.0是专业版或者企业版,因为只有这两个版本的VC6.0才支持配置文件功能。好了,闲话不说了,进入正题。
启动函数配置文件(function profiling)功能。首先点击“工程”,然后选择“设置”调出工程/项目设置对话框,然后选择“链接”(Link)标签,在“分类”(Category)下拉框里面选择“常规”(General),然后把“允许配置文件”(Enable Profiling)打上勾就行了。
启动代码行配置文件(line profiling)功能。首先进行上述启动函数配置文件的操作,然后再点选了“允许配置文件”(Enable Profiling)后,在把“产生调试信息”(Generate Debug Info)的勾打上,然后转到“C/C++”标签下,在“分类”(Category)下拉框里面选择“常规”(General),然后在“调试信息”(Debug Info)下拉框里面选择“程序数据库”(Program Database)或者“仅行号”(Line Numbers Only),然后确定就可以了。
不管是启动函数配置文件,还是启动代码行配置文件,在设置完成后,都需要对项目重新组建(Build)一下。另外,如果在“链接”(Link)标签页中点选了“允许配置文件”(Enable Profiling)的话,就会关闭增量链接(incremental linking)功能。也就是说,项目每次改动后,在组建时都会重新组建整个项目,而不是只组建改动的部分。当然,将“允许配置文件”(Enable Profiling)的勾点掉的话,就会重新启动增量链接功能。
好了,进行完必要的设置后,让我们来看看怎么用这个配置文件功能。选择“组建”,然后选择其下面的“配置文件”,在弹出的对话框里面有“记时功能”(function timing)、“功能覆盖”(function coverage)、“行覆盖”(line coverage)、“合并”(merge)和“定制”(custom)。“合并”不用多说了,就是将多个“配置文件”合并为一个配置文件,这样省的一个一个地去运行了。“定制”可以用命令行的方式来运行含有配置文件指令的批处理文件。“记时功能”就是测试程序运行时,每一个被执行的函数所花费的时间。从“记时功能”可以看出,配置文件功能的确是用来进行性能优化的。实际上,“记时功能”也是配置文件功能中,使用最多的一个,只不过很多传说中的编程高手更喜欢在代码里面嵌入GetTickCount()函数来实现,嘿嘿。
既然是玩,那咱就重点看看“功能覆盖”(function coverage)和“行覆盖”(line coverage)这两项。先看“功能覆盖”(function coverage)。选好该项后,点“确定”。程序在运行结束后,在VC的信息窗口中会列出一个函数清单,其中标星号(*)的函数是被执行过的,没有标星号的就没有被执行。另外,每个函数的后面也会给出该函数所在的代码模块。下面是一个示例清单:
Covered Function
------------------------------------------
. InitInstance (generic.obj)
. LoadAcceleratorsA@8 (user32.def)
* _LoadCursorA@8 (user32.def)
. LoadIconA@8 (user32.def)
. SendMessageA@16 (user32.def)
* SetCursor@4 (user32.def)
. _SetDlgItemTextA@12 (user32.def)
再看另外一个功能“行覆盖”(line coverage)。选好该项后,点“确定”。程序在运行结束后,在VC的信息窗口中会列出一个源代码清单,其中标星号(*)的是被执行过的,没有标星号的就没有被执行。使用“行覆盖”(line coverage)功能测试程序时,程序的运行速度会比一般运行时要稍慢。另外,不管有没有被执行,程序中包含的所有源代码都会被列出来。下面是使用“行覆盖”(line coverage)测试程序的一个示例清单:
Line Covered Source
-----------------------------------------------------
1: // waste.c
2:
3: #include
4:
5: void WasteTime(HANDLE hInstance, HWND hWnd)
6: * {
7: LONG lCount, lX;
8: HCURSOR hOldCursor;
9: * hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
10: * for(lCount = 0; lCount < 1000L; lCount++) {
11: * lX = 57L;
12: * }
13: * if(lCount == 0) {
14: . lCount = 1; // should never execute
15: }
16: * SetCursor(hOldCursor);
17: * }
此外,对于命令行程序,也可以设置它的命令行参数。具体做法是,选择“工程/项目”,然后选择“设置”,点选“调试”(debug)标签,然后在“程序变量”里面输入要运行的命令行参数就ok了。
如果你只想对特定的文件进行“功能覆盖”(function coverage)和“行覆盖”(line coverage)测试,那么可以在配置文件对话框的“高级设定”(Advanced settings)文本框里面,先输入 /EXCALL 来排除测试所有的程序模块(obj文件)和库文件(lib),然后再在后面跟上 /INC 来包含进你想测试的那个特定模块的文件,就像下面这样:
/EXCALL /INC file1.obj /INC file2.obj //仅测试file1和file2
如果你仅仅想测试某个特定模块中的其中几行,那么可以上面命令中的文件后面加上括号,里面填上想要测试的起始行和终止行就行了,就像下面这样:
/EXCALL /INC file1.cpp(32-96) //仅测试file1中的32行到96行
而如果你想在测试中排除某一个或几个特定的模块的话,用
/EXC就行了,就像下面那样:
/EXC file1.obj /EXC file2.obj //测试时排除file1和file2
好了,今天就先到这吧,各位如果有兴趣的话,可以自己试试。当然,配置文件还有好多好多好玩的功能,而且除了配置文件外,还有很多好用的工具,如SPY++。我个人觉得在一个模块完成后,用行覆盖和功能覆盖来对其进行前期的测试,还是很不错的,你们说呢。