.NET Core 性能分析: xUnit.Performance 简介
xunit-performance 是xUnit的一个扩展, 使用它可以对.NET Core项目进行性能测试。
官网:https://github.com/Microsoft/xunit-performance
xUnit大家可能都用过,它是用来做单元测试的,它可以很快给开发人员功能是否OK的反馈。
和xUnit一样,xUnit-Performance可以很快给出性能上的反馈。
准备和安装xUnit-Performance
为了讲解,我们需要准备一个需要被测试的项目和一个测试项目。
我使用Visual Studio 2017建立项目之后总有一些问题,不过后来我是用dotnet cli和VSCode就没有什么问题了。
建立项目的顺序如下:
1. 首先使用dotnet cli建立一个classlib类型的被测试项目,它的目标框架是.NET Standard 2.0:
这个项目里只有一个类,也就是要被测试的类:
这个类有三个方法,分别是使用foreach,for和Linq扩展方法的Sum对集合循环并求和。
2. 使用dotnet cli建立一个console项目(如果使用VS2017的话直接建类库就可以,因为VS2017内置Test Runner),这个是测试项目,它的版本只能是2.0(可能是因为我电脑sdk的版本较老):
另外还需要引用被测试项目。
3.然后,按照官方文档安装两个库。
xUnit-Performance目前还处于Beta阶段,这两个库需要按照官网的指示进行安装:
最新版的xunit.performance.api.dll, 这里用到的是MyGet: https://dotnet.myget.org/feed/dotnet-core/package/nuget/xunit.performance.api#.
然后是最新版的 Microsoft.Diagnostics.Tracing.TraceEvent, 这个使用Nuge: https://www.nuget.org/packages/Microsoft.Diagnostics.Tracing.TraceEvent
OK,现在依赖库都装好了。
编写性能测试
性能测试和单元测试略有不同, 性能测试是跑很多次, 然后取平均值. 同时也要考虑到内存等其它因素的影响.
在性能测试里就不需要测试功能的正确性了, 但是程序在压力下可能会产生不同的结果, 尤其是多线程的情况. 这时你就需要写压力测试了.
而对于性能测试, 我们只考虑速度.
由于我是用的是dotnet cli和VSCode,所以测试项目我选用的是控制台项目,它的Main方法需要这样写:
如果您能成功的使用VS2017建立测试项目,那么就不需要Main方法了,建立一个类库项目即可,直接使用VS2017的Test Runner即可。
性能测试代码
下面我们编写性能测试方法。
首先在测试项目建立一个类,然后做一些准备工作:
这里我准备了一个List<KeyValuePair<int, double>>,它有100000条数据,是随机生成的。
然后是测试方法,在这里我们使用[Benchmark]替代了xUnit单元测试中的[Fact]:
xUnit.Performance的测试会跑很多次,结果是取平均值的。
这里我们循环遍历Benchmark.Iterations,它有一个默认值,我这里默认是跑了1000次循环。
再循环里,首先您可以做一些准备工作。然后使用iteration.StartMeasurement()来开始进行测量。
只有iteration.StartMeasurement()后边的部分才会被测量,在大括号里面写被测试相关的代码就可以了。
然后在命令行输入运行测试:
dotnet run --perf:collect stopwatch
测试结果如下:
提供了控制台输出,xml,csv,md输出(在项目文件夹里)。
从控制台可以看到该测试的循环跑了1000次,平均结果是0.963毫秒。
下面是csv结果的截图:
下面是md结果文件的截图:
下面是xml结果文件的截图,它里面有详细数据:
内部循环
xUnit.Performance还可以添加一个内部循环属性 InnerIterationCount。先看代码,添加以下方法:
[Benchmark(InnerIterationCount = 10_000)],这里的InnerIterationCount是内部循环遍历的次数。
在StartMeasurement()之后,进行内部循环。
这样的话,外层循环的次数可能会很少,而且第一次外层循环是热身,不包括在测试结果中。
而内部循环适合于运行比较快速的代码(微秒级)。
有时确实需要这样两层循环,做一些热身工作或者需要完成不同级别的准备工作。
然后我们来跑测试
在结果里看到外层循环有2次的记录,但是它实际跑了3次,第一次算作热身,不做统计。
它的时间是内层循环的总和,除以10000之后,和第一个方法的结果差不太多。
我可以在方法中打印输出循环次数:
其结果如下:
可以看到确实是跑了3次,但统计了2次。
然后我再添加另外两个测试方法,分别测试另外两个方法:
运行测试:
可以看到现在这4个测试方法的结果。
看来针对List来说foreach要比linq和for循环快。
注意foreach测试的外层循环跑了2次,而for和linq的测试循环只跑了1次,可能是因为花费时间太久了吧?这个我不太确定。
StopWatch
可以看到测试命令的参数 stopwatch,它应该是来自System.Diagnostics命名空间下的StopWatch类。
它有Start()和Stop()方法和一些其它属性用来统计逝去的时间。
StopWatch类是跨平台的,但是在其它系统上,它只能统计时间;而在Windows上,它还可以使用内核ETW events和CPU性能计数来给您更多的数据,具体请查阅相关资料。
结语
该库还有很多功能和命令的参数,具体请参考文档:https://github.com/Microsoft/xunit-performance
但是要注意,它仍然是beta状态,只能在MyGet而不是Nuget获取。
博客文章可以随便转载和抓取.
.NET Core 性能分析: xUnit.Performance 简介相关推荐
- chrom 性能分析工具 Performance
在chrom的工具栏,有一个面板performance,点开之后操作后,你会看到一堆五颜六色的图表,但是具体是干什么的,未可知 performance面板是Chrome 的性能分析工具,那应该和页面有 ...
- 系统级性能分析工具perf的介绍与使用
测试环境:Ubuntu16.04 + Kernel:4.4.0-31 apt-get install linux-source cd /usr/src/tools/perf make &&am ...
- linux 系统级性能分析工具 perf 的介绍与使用
目录 1. 背景知识 1.1 tracepoints 1.2 硬件特性之cache 2. 主要关注点 3. perf的使用 3.0 perf引入的overhead 3.1 perf list 3.2 ...
- 分析linux系统的运行性能,Linux系统的性能测试与性能分析
Linux系统的性能测试与性能分析 发表于:2012-12-03来源:一淘测试作者:若凌点击数: Linux系统的性能测试与性能分析1 性能测试简介 性能测试的过程就是找到系统瓶颈的过程. 性能测试( ...
- 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)
议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...
- 二分查找树性能分析(Binary Search Tree Performance Analysis)
经典算法系(21)-二分查找树性能分析(Binary Search Tree Performance Analysis)https://www.douban.com/note/221942390/ ...
- gbd 分析core文件_Go 性能分析工具 pprof 入门
(给Go开发大全加星标) 来源:wudaijun https://wudaijun.com/2018/04/go-pprof/ [导读]pprof是golang用于性能分析的工具.可以生成图形和文本报 ...
- .NET Core引入性能分析引导优化
"性能分析引导优化(Profile Guided Optimization,缩写PGO)"是一项原生编译技术,可用于生成高度优化的代码.它通过一个两步编译过程实现优化--用第一步记 ...
- 老李分享:《Java Performance》笔记1——性能分析基础
老李分享:<Java Performance>笔记1--性能分析基础 1.性能分析两种方法: (1).自顶向下: 应用开发人员通过着眼于软件栈顶层的应用,从上往下寻找性能优化的机会. (2 ...
最新文章
- NLP汉语自然语言处理入门基础知识介绍
- MFC类向导添加自定义消息未声明标识符的解决方法
- post请求改成body_如何使用BODY快速发送POST请求
- 如何选择漏电保护器规格型号_老师傅告诉你:电路跳闸如何解决
- linux监控mysql性能,MySQL 性能监控4大指标——第二部分
- java url拦截器框架_使用Spring Interceptor实现URL访问校验
- cordova build android很慢,cordova build --release android命令打包下载gradle非常慢的问题...
- How to change context root of a dynamic web project in Eclipse
- 如何学好Python自动化,每个进阶的测试人都应该看看
- 解决被西刺代理封ip的问题
- 华为eNSP基本操作
- 软考网络工程师必过教程---必看
- Oracle如何卸载、清理干净
- 如何修改开机背光亮度
- Pr学习笔记——添加字幕流
- python常用模块与MySQL数据库交互(学习笔记)
- Affine set 和 convex set 的定义
- 【精品推荐】130个令你眼前一亮的网站,总有一个你用得着(转)
- 表单注册表单注册表单注册
- python求三位数的最大公约数和最小公倍数(3种算法)
热门文章
- mysql 面试知识点笔记(七)RR如何避免幻读及非阻塞读、范式
- 受 SQLite 多年青睐,C 语言到底好在哪儿?
- 自定义Cell的流程
- 使用chpasswd命令批量修改系统用户密码
- 分享一个点赞超过100的漂亮ASP.NET MVC蓝色界面框架
- 我的Android进阶之旅------Android MediaPlayer播放mp3的实例--简易mp3播放器
- 模块XX.dll已加载,但对DllRegisterServer的调用失败
- 一起谈.NET技术,发布NGuestBook(一个基于.NET平台的分层架构留言本小系统)
- MariaDB Spider 数据库分库分表实践 
分库分表
- .NET6之MiniAPI(七):中间件