使用 dotTrace 分析 .NET Core 代码问题

在项目开发之中,前期可能主要以保证任务完成为主,对于性能优化主要在于开发完成之后再来进行。可能在测试的时候发现部分接口的代码执行时间过长,但是又毫无头绪,这个时候你就需要性能分析工具来协助你排查问题了。

常规性能分析借助于 Visual Studio 强大的性能测试工具就可以进行分析,但是这些功能只包含在企业版当中。这个时候我们就可以使用 JetBrains 的 .NET 分析全家桶来进行这个操作了,其包含内存分析(dotMemory)与性能分析(dotTrace),其实他的 dotCover(单元测试) 也是挺好用的。

1.安装与下载 1.1 下载

安装步骤较为简单,前往 Jetbrains 官网,找到 dotTrace ,点击下载即可。

其地址为 https://www.jetbrains.com/profiler/download/ ,选择自己需要的安装包形式,一般选择 WebInstaller 进行安装,当然这里推荐选择 Standalone (独立版),直接下载运行就 OK 。

1.2 安装

每个用户可以免费评估使用 10 天,当然你要使用某些补丁或者激活工具也是可以的,这里不再详述过程,只是注意一下(WebInstaller)在安装的时候选择自己需要的安装就可以了,不需要的直接选为 Skip 跳过。

使用 dotTrace 分析 .NET Core 代码问题

你也可以在安装的时候选择 "Visual Studio Integration",这样就会与 VS 集成,在分析代码的时候可以快速跳转到相应的代码行。

使用 dotTrace 分析 .NET Core 代码问题

2.使用与分析

dotTrace 使用比较方便,本身支持 .NET Core 分析,分析时只是会有四种不同的分析模式,这里大概讲解一下各种分析模式的区别。

使用 dotTrace 分析 .NET Core 代码问题

Profiler Options 作用与描述
Sampling   通过获取 CLR 内部一个方法开始执行和结束执行的时间差来计算的分析时间。
这是最快的方法,它用于精确测量程序运行时间,但可能会丢失一些数据。
使用此配置类型可使你快速获取应用程序的的总体性能。
 
Tracing   慢于 Sampling 的方法,但是可以准确地测量特定方法被调用的准确次数。
它是通过获取 CLR 内部一个方法开始执行和结束执行的时间差来计算的分
析时间。
 
Line-by-line   通过收集代码执行的每条语句的时间来进行比较,它计算出的时间更加精确。
该方法适用于你已经知道性能问题大概在哪里出现,并要找到具体某一个出
现性能问题的时候。
 
Timeline   采取抽样的方式,每隔一段时间 (10 ms),会暂停所有线程,并抓取堆栈里的
信息,然后才计算出代码执行时间差。使用这个方式可能会导致一些执行时间
少于 10 ms 的方法无法被抓取到。
 

一般来说我们使用的是 Tracing 来进行代码的性能分析,因为一般都是需要查看每个方法具体的调用时间。下面我就将以一个接口的实例来作为示范,看如何来排查调用缓慢的问题。

2.1 获取快照信息

首先运行 dotTrace 之后,选择 .NET Core Application,之后右侧的 Profiler Options 则选择 Tracing。最后一步则是选择需要进行检测的 dll 文件,这里我选择的是一个基于 Abp 框架开发的 ASP.NET Core 项目。

使用 dotTrace 分析 .NET Core 代码问题

当然,你也可以勾选上 Advanced ,配置诸如启动参数之类的东西,之后点击 Run 则开始进行分析了。

使用 dotTrace 分析 .NET Core 代码问题

这里右下角的 Get Snapshot and Wait 点击之后呢,就会获取到快照文件了,当然现在先不慌,我们先来测试一下我们要测试的接口。

比如说我这里有一个 TestMethod 方法,其代码如下:

public class TestApplicationService : ApplicationService { private readonly IRepository<SysSystem> _tempRep; public TestApplicationService(IRepository<SysSystem> tempRep) { _tempRep = tempRep; } public async Task<string> TestMethod() { var systems = _tempRep.GetAll().ToList(); foreach (var system in systems) { system.Status = 10; await _tempRep.UpdateAsync(system); } int i = 0; for (int j = 0; j < 10000; j++) { i += j; } return systems[0].SystemCode; } }

现在我们通过 SwaggerUI 调用这个接口,看需要多长时间。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgswg.html