最近测试报了一个问题:页面加载慢,代码慢怎么办,代码慢在了哪里呢?于是决定使用DotTrace来进行性能分析,简直打开了通往新世界的大门,玩儿起来太爽了。接下来我用这篇实践来手把手教大家怎么玩儿DotTrace.
- DotTrace简介,简单介绍DotTrace如何使用,安装方式,配置说明
- DotTrace实践,使用DotTrace进行列表加载慢、导出慢的问题分析,如何使用DotTrace进行性能分析,包括Controller接口调试以及单元测试接口调试
好,接下来就依据目录顺序来讲解下。
DotTrace简介
什么是DotTrace,在项目开发之中,前期可能主要以保证任务完成为主,对于性能优化主要在于开发完成之后再来进行。可能在测试的时候发现部分接口的代码执行时间过长,但是又毫无头绪,这个时候你就需要性能分析工具来协助你排查问题了。就像我现在遇到的情况,别人说你慢,你得查出哪里慢,是否能优化,如果不慢,确实需要那么多时间,你也可以给出证据。
DotTrace安装
我这里使用的是VS2019集成版,你也可以考虑使用本地安装包,简单介绍下集成的安装方式,如果需要本地安装包可以私聊我。首先通过VS的扩展搜索联机搜索DotTrace,点击扩展----管理扩展,然后如下图所示安装:
然后在镜像文件点击安装即可,我这里已经安装了,所以显示的是Repair,大家安装的时候可以选择Install:
安装好之后可以通过如下方式打开进行分析:点击扩展------点击ReSharper-------点击Profile-------点击 Run Application Performance Profiling,然后就可以召唤出调试选项啦,我这里使用的本地IIS站点调试,当然也可以直接附加到对应的进程上调试。
点击run之后刷新站点页面,将站点host到本地,准备好之后点击start开启分析,分析完成后点击Get Snapshot and Wait ,读取快照信息:
当然还有一种方式,直接在单元测试上就可以开启分析:
DotTrace参数说明
在上图的使用说明中,我们可以看到如下几个参数,我比较推荐Tracing和Line-by-Line,其实就比较够用了。
Profiler Options | 作用与描述 | 场景分析 |
Sampling | 通过获取 CLR 内部一个方法开始执行和结束执行的时间差来计算的分析时间。这是最快的方法,它用于精确测量程序运行时间,但可能会丢失一些数据。使用此配置类型可使你快速获取应用程序的的总体性能。 | 这适用于大多数场景。尤其是如果你还没有对你的程序进行过任何性能分析的情况下,先使用这个选项进行一个初步分析大致确定性能问题是很方便的。 |
Tracing | 慢于 Sampling 的方法,但是可以准确地测量特定方法被调用的准确次数。它是通过获取 CLR 内部一个方法开始执行和结束执行的时间差来计算的分析时间。 | 如果你使用 Sampling 分析方式得不到你想要的性能分析数据的时候,你可能用得到此选项。例如,当你分析算法复杂度,需要明确知道方法的调用次数,而不需要知道方法的准确执行时间的时候。 |
Line-by-line | 通过收集代码执行的每条语句的时间来进行比较,它计算出的时间更加精确。该方法适用于你已经知道性能问题大概在哪里出现,并要找到具体某一个出现性能问题的时候。 | 当你已经通过其他方法得知性能问题出现在哪个具体的方法时你可能需要用到这个选项,这会分析此方法的每一行代码。 |
Timeline | 采取抽样的方式,每隔一段时间 (10 ms),会暂停所有线程,并抓取堆栈里的信息,然后才计算出代码执行时间差。使用这个方式可能会导致一些执行时间少于 10 ms 的方法无法被抓取到。 | 推荐用于大多数情况,尤其是分析多线程应用程序的时候。你可以用这个选项来确定 UI 卡顿或不响应的原因,可以分析过多的 GC(垃圾回收),可以分析不均匀的工作负载分配、IO 不足或者其他各种异常。 |
DotTrace实践
接下来就来分别分析下代码慢的问题,由于涉及到公司的代码,不便使用其快照信息,我们自己写个单元测试看看它的性能怎么样。
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace UnitTestProject1 { [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { var result = 0; for (var i = 0; i < 1000; i++) { result += i + 10; } for (var i = 0; i < 10000; i++) { result = GetDouble(result); } Assert.IsNotNull(result); } public int GetDouble(int single) { return single * 2; } } }
点击分析后获取到快照,然后在快照里搜索我们想要的方法:
搜索该方法,我们就可以看到该方法以及其调用的方法链中各个方法的调用时间,甚至能直接对比到每一行的代码性能损耗:
因为我们这个是比较简单的单元测试,所以前后耗时不过1毫秒。
当然我们选中方法,右击属性还可以看到具体单次调用时间,可以看到单次调用不过1us,可以说快的飞起。
写在最后
刚开始用这个工具玩儿的特别开心,感觉能透过表层直接看到本质,可以直接越过现象发现本质问题,项目中分析出了两个浅层不易发现的问题很开心,就像治病救人一样hhhh。发现jetbrains全家桶真的太强了,大佬说性能调优是迈向高阶开发的第一步,希望能越走越远吧。