Author: 王晓亮
Date: 2008年10月26日
导读通过上一篇文章,相信大家已经对AQTime有了初步的认识,并能够上手做简单的性能优化工作,这篇文章我们重点说说在开始收集数据前关于AQTime的配置细节,合理的配置是保证最后能收集到理想数据的基础,所以很重要。
记得留下宝贵意见哦!!! 源代码下载:
首先,阅读此篇文章之前,请确认已经认真看过[上一篇]文章。在这篇文章理,我们分别从范围、粒度、过程三个方面介绍AQTime的配置问题;
1. 配置分析范围
AQTime 默认会分析所有的.NET 代码,包括底层的类库,范围越大,意味着最后收集到的结果就越多,虽然有时能分析的范围越大越好,但是当项目很庞大,而我们需要有针对性地对某些模块局部进行性能优化的时候,缩小包围圈,集中优势兵力各个击破就显得很有必要。另外很多时候因为项目中不同模块的分工不同,所以有选择地分析自己负责的部分也是高效完成任务的需要。
AQTime 主要有两种不同维度的方式控制分析范围:
a.使用EnvironmentOptions 选项里的Exclude routines with no source info :
该选项决定AQTime 只分析带有pdb 文件且包含了源代码信息的程序集,这个选项一般在开发调试阶段比较常用,因为在产品没有正式发布前,本地环境应该都是带pdb 文件和源代码信息的,使用这个选项可以有效地控制收集分析结果的范围,提高定位性能瓶颈的效率。
b.使用Area:
首先介绍一下Area ,在AQTime 的官方使用手册里可以找到"Defining Areas to Profile" 一节,这部分一开头就说到:“AQTime offers several means of restricting what parts of an application get profied.Profiling areas(with the associated checking) are perhaps the most important of these means.” 这段的意思大概是说AQTime 提供了几种手段来限制应用程序那部分会被分析,而Area 是其中最重要的一种手段。那么Area 到底是什么 呢?其实一个Area 就是在AQTime 中定义的一个虚拟的范围( 空间) ,分析性能的时候,你可以把任意模块、或模块里的任意方法扔到这个Area 里,每个Area 又分为Including 和Excluding 两种类型,顾名思义,Including 就是分析收集结果是要包含的,Excluding 正好相反。(这块稍后介绍粒度时再详细说)
如上图所示,每次新建AQTime 的项目后,在setup 页签的Areas 部分都会有预置好的两个部分,如图中红框部分。其中“profile Entire .NET Code” 部分如果选中前面的复选框,则会默认分析应用程序执行过程中加载的所有托管.NET 程序集,也就是说这是个超集,如果你已经选择了这个,那么其他Area 选不选都没什么意思啦,因为那些都是这个的子集而已。“Full Check” 部分如果选中前面的复选框,表示分析范围是左边的Modules 列表里的所有模块,如果只选中这一个范围,那么AQTime 的分析范围就完全决定于你已经加载了多少个模块(Module) 了。
如图所示,可以通过菜单或鼠标右键里的“Add Area...”来创建Area,在弹出的子窗体里输入Name,在指定一下Type和Level就可以了,关于Type和Level我们善后在“配置分析粒度”一节里详细介绍。
如上图所示,在设置好你的Area以后,可以把整个模块(如App_Web_szkxjxyb.dll)或模块中的具体方法(如Data2UI方法)直接拖拽到你自定义的Area里,这样的Area你可以随便自定义创建任意多个,选中Area前面的复选框以后,AQTime在分析应用程序的时候,就会按Areas里设置的范围,有针对性的进行性能数据的收集了。
2. 配置分析粒度
在上一节“配置分析范围”里,我有意忽略了“分析粒度”的细节,这一节我们详细说明配置分析粒度的问题。
分析粒度的问题,还是从上图开始比较直观,在AQTime里,所谓的分析粒度有两种,即上图中的“Type”和“Level”;这里的Type只是相对于自定义的Area来说的,Including类型应该比较好理解了,我们一般用的都是这个,举例来说一下Excluding,比如你在用AQTime跑一个有10个模块的应用程序,你很明确其中A、B两个模块已经进行过优化或其它原因导致你并不关心这两个模块的性能问题,也就是说不想在AQTime收集的分析结果里看到任何跟A、B有关系的东西,那么你就创建一个Area,起名叫“I Hate You!”,然后将其Type设置为Excluding,再把A、B两个模块都拖到这个Area里,然后同时选中“I Hate You!”和“profile Entire .NET Code”,那么AQTime跑起来后就只会收集整个应用程序除了A、B以外的所有模块的数据了!
搞定了Type,再来说一下Level,这个就很好理解了,Routine表示统计到方法的级别,Line表示统计到行的级别。Class表示统计到类的级别,但是“The class level profiling areas are supported by the Allocation profiler only.”(引自AQTime使用手册),一般Routine比较常用,偶尔会用到Line,不过设置成Line的时候,肯定会比较慢,如果应用比较大,对机器的硬件配置要求就会比较高了。
上图是自定义Area不同的粒度时对应的不同图标,来源于AQTime使用手册。
3. 配置分析过程
默认情况下,AQTime是会分析程序的整个生命周期的,包括底层框架部分,而一般情况下(专门研究底层框架除外),我们并不关心程序的整个生命周期,可能只是关注其中的某一段,也就是说最好可以通过配置AQTime,让其只收集我们关心的这段生命周期的性能数据(其实也相当于配置分析范围)。
通过工具栏上的(Profiling)功能,既可以实现这个美好的愿望了!如上图所示,举例来说,假如我们正在分析一个订单模块保存功能的性能,也就是说我们只关心从点击保存按钮开始,到保持成功这段生命周期的性能问题,我们只想收集这期间的性能数据就OK了!那么参考上图,A 表示用AQTime启动程序之前,我们要把
设置为
状态,表示不收集性能数据;B 表示启动程序以后,进入新增订单页面,录入所有必输项,准备好执行保存操作,这期间
仍然要保持
状态,也就是说,从程序启动到后面的一系列操作,AQTime都没有收集性能数据;C 表示在开始执行保持操作之前,要先把
恢复为
状态,表示从此开始要收集性能数据了,然后才执行保存操作。保存操作执行完后,程序提示保存成功,此时要通过
收集这段生命周期的数据,到此为止,一个完整的收集某一段生命周期性能数据的过程就结束了,剩下的就是拿出200%耐心仔细去分析收集到的结果了。
总结:本来这篇文章准备写两部分,第一部分就是上面这些了,第二部分是想在通过一个实例来巩固一下第一部分和在上一篇文章里学到的内容,但是当我写完第一部分以后,发现内容已经不少了,所以决定把第二部分单独成文放在下一篇文章里,不过因为Demo 已经准备好了,还是上一篇文章用过的那个程序,不过我在里面埋了好几个地雷,所以这次一起先把Demo 放出来,大家可以通过最上面导读的链接去下载,希望大家可以运用这两篇文章学到的知识,把地雷都挖出来,找到地雷的工兵们请在留言里留下地雷的具体位置和发现过程,大家可以广泛交流,下一篇文章我们将具体讲解挖雷过程。OK, 就说这么多啦,希望大家挖的开心。