.NET Core中的性能测试工具BenchmarkDotnet

背景介绍

之前一篇博客中,我们讲解.NET Core中的CSV解析库,在文章的最后,作者使用了性能基准测试工具BenchmarkDotNet测试了2个不同CSV解析库的性能,本篇我们来详细介绍一下BenchmarkDotNet。

原文链接:https://dotnetcoretutorials.com/2017/12/04/benchmarking-net-core-code-benchmarkdotnet/

为什么需要性能基准测试?

性能基准测试可以帮助程序员对比2个代码段或者方法的性能,这对于代码重写或者重构来说,可以提供一种很好的量化标准。如果没有性能基准测试,很难想象将方法A改为B方法时候,仅凭肉眼如何区分性能的变化。

BenchmarkDotNet

640?wx_fmt=png

BenchmarkDotNet是一款强力的.NET性能基准测试库, 官网https://benchmarkdotnet.org/。

运行时支持

  • NET Framework (4.6+),

  • .NET Core (2.0+)

  • Mono

  • CoreRT。

BenchmarkDotnet为每个被测试的方法提供了孤立的环境, 使用BenchmarkDotnet, 程序员可以很容易的编写各种性能测试方法,并可以避免许多常见的坑。

代码基准测试(Code Benchmarking)

现在我们希望来对比一下Linq to object中First和Single方法的性能

虽然我们知道First的性能肯定比Single高, First方法会在查询到第一个满足条件的对象之后就停止集合遍历,而Single找到第一个满足条件的对象之后,不会停止查找,它会去继续查找集合中的剩余对象,直到遍历整个集合或者在集合中找到第二个匹配条件的对象。 这里我们只是为了演示一下如何进行代码基准测试。

为了使用BenchmarkDotNet来进行代码基准测试,我们首先创建一个空的.Net Core控制台程序。

640?wx_fmt=png

然后我们使用Package Manage Console添加BenchmarkDotNet库

PM> Install-Package BenchmarkDotNet

然后我们修改Program.cs文件, 代码如下

640?wx_fmt=png

代码解释说明

  • 以上代码中SingleVsFirst类是一个测试类。

  • 测试类中我们生成了一个拥有100万对象的字符串集合。

  • 我们在集合的中间位置插入了一个测试字符串,字符串的内容是"needle"。

  • 代码中的SingleFirst方法,分别调用了Linq to object的SingleOrDefaultFirstOrDefault方法来查询字符串集合中的"needle"字符串。

  • SingleFirst方法上,我们加入[Benchmark]特性, 拥有该特性的方法会出现在最后的基准检测报告中。

注意:

  • 测试的方法必须是公开的(public), 如果把public去掉,程序不会产生任何结果

  • 在运行程序之前,还有一步关键的操作,测试的程序需要使用Release模式编译,并且不能附加任何调试器(Debugger)

最终结果

现在我们运行程序,程序产生的最终报告如下

Method  |     Mean |     Error |   StdDev |   Median |
------- |---------:|----------:|---------:|---------:|Single | 28.12 ms | 0.9347 ms | 2.697 ms | 28.93 ms |First | 13.30 ms | 0.8394 ms | 2.475 ms | 14.48 ms |

结果中的第一列Mean表明了2个方法处理的平均响应时间,FirstSingle快了一倍(这和我们测试字符串放置的位置有关系)。

带测试参数的基准测试(Input Benchmarking)

BenchmarkDotNet中我们还可以使用[ParamsSource]参数来指定测试的用例范围。
在上面的代码中,我们测试了匹配字符串在集合中间位置时,FirstSingle的效率对比,下面我们修改上面的代码,我们希望分别测试匹配字符串在集合头部,尾部以及中间位置时FirstSingle的效率对比。

640?wx_fmt=png

代码解释说明

  • 我们创建了测试的用例字符串集合_needles

  • 在构造函数中,我们在字符串集合的头部,中部,尾部分别插入了3个字符串

  • 我们添加了一个属性Needle, 表示当前测试的用例,在被测试SingleFirst方法中,我们使用属性Needle来匹配

  • 在属性Needle上我们加上了参数来源特性[ParamsSource], 并设置参数来源是_needles

最终效果

现在我们运行程序,程序产生的最终报告如下

 Method |       Needle |             Mean |          Error |           StdDev |           Median |------- |------------- |-----------------:|---------------:|-----------------:|-----------------:|Single |    EndNeedle | 23,266,757.53 ns | 432,206.593 ns |   591,609.263 ns | 23,236,343.07 ns |First |    EndNeedle | 24,984,621.12 ns | 494,223.345 ns |   783,890.599 ns | 24,936,945.21 ns |Single | MiddleNeedle | 21,379,814.14 ns | 806,253.579 ns | 2,377,256.870 ns | 22,436,101.14 ns |First | MiddleNeedle | 11,984,519.09 ns | 315,184.021 ns |   924,380.173 ns | 12,233,700.94 ns |Single |  StartNeedle | 23,650,243.23 ns | 599,968.173 ns |   714,219.431 ns | 23,555,402.19 ns |First |  StartNeedle |         89.17 ns |       1.864 ns |         2.732 ns |         89.07 ns

从结果上看

  • 当匹配字符串在集合头部的时候,First性能比Single高的多

  • 当匹配字符串在集合中部的时候,First性能是比Single的一倍

  • 当匹配字符串在集合尾部的时候,First和比Single的性能差不多

加入内存测试

在.NET Core中的CSV解析库中,我们使用了以下代码

640?wx_fmt=png

其中除了[Benchmark]特性,我们还在测试类CsvBenchmarking上添加了[MemoryDiagnoser]特性,该特性会在测试报告中追加,2个方法执行时的内存使用情况。

        Method |       Mean | Scaled | Allocated |-------------- |-----------:|-------:|----------:|CSVHelper | 1,404.5 ms |   1.00 | 244.39 MB |TinyCsvParser |   381.6 ms |   0.27 |  32.53 MB |

其中Allocated表明了内存占用情况。

总结

BenchmarkDotNet绝对是.NET开发人员了解代码性能,以及对比代码性能的必备神器。你的项目里用了BenchmarkDotnet了么?

相关文章:

  • 使用 BenchmarkDotnet 测试代码性能

  • .NET Core性能测试组件BenchmarkDotNet 支持.NET Framework Mono

  • 用BenchmarkDotNet给C#程序做性能测试

原文地址:https://www.cnblogs.com/lwqlun/p/9671611.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319852.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

序列求和

来源:牛客网 文章目录题目描述题解:代码:时间限制:C/C 1秒,其他语言2秒 空间限制:C/C 131072K,其他语言262144K 64bit IO Format: %lld题目描述 定义S(n) 12 22 … n2,输出S(n) …

【区间DP】摆渡线路(2017 特长生 T4)

题目大意 给出一个园,圆上有100个点,若干条弦,让你选择尽量多互不相交的弦(点可以重合) 解题思路 可以把圆展开成链,然后复制一遍 设fi,jf_{i,j}fi,j​为第i个位置到第j个位置的所选弦的数量 那么可以枚…

bzoj4589-Hard Nim【FWT】

正题 题目链接:https://darkbzoj.tk/problem/4589 题目大意 求有多少个长度为nnn的数列满足它们都是不大于mmm的质数且异或和为000。 解题思路 两个初始多项式F[0]1F[0]1F[0]1,G[prime≤m]1G[prime\leq m]1G[prime≤m]1,然后答案就是FxorGnF\ xor\ G^…

some useful tricks

异或题思考方向&#xff1a;01trie树&#xff0c;分治 2. 二分图最大匹配&#xff0c;最大独立集互相转换 3. Snow 4. Code 5. Code 6. Code 7. 题目 #include<iostream> #include<cstdio> using namespace std; const int N100010; int n,p,nxt[N],no[200]…

25大技术主题向您发出最后一次约【惠】邀请

一年一度的微软技术盛会即将在上海世博中心拉开大幕金秋十月&#xff0c;来自两岸三地的百名明星讲师将携 25 大技术主题&#xff0c;齐聚上海为您奉献一场无与伦比的技术视听盛宴您&#xff0c;准备好了吗&#xff1f;25大技术主题公开&#xff0c;不负期待姗姗来迟的5系25大技…

P4980-[模板]Pólya定理

正题 题目链接:https://www.luogu.com.cn/problem/P4980 题目大意 nnn个物品图上mmm种颜色&#xff0c;求在可以旋转的情况下本质不同的涂色方案。 解题思路 既然是群论基本题就顺便写一下刚刚了解到的相关知识把&#xff08;顺便消磨一下时间 一个群(G,)(G,\times )(G,)定义…

逆元的求法

逆元&#xff1a; 对于a和p&#xff0c;若 a * inv(a) % p ≡ 1&#xff0c;则称inv(a)为a%p的逆元。其中p为质数 逆元就是在mod下&#xff0c;不能直接除以一个数&#xff0c;而要乘以他的逆元 a * inv(a) 1 (mod p) x / a可以改成 x * inv(a) % p 文章目录方法一.扩展欧几里…

[CF995F] Cowmpany Cowmpensation(树形dp,拉格朗日插值)

树形DP&#xff1a; 设f[u][i]f[u][i]f[u][i]表示给uuu的子树分配工资&#xff0c;uuu点工资为iii的方案数 f[u][i]∏v∈sonu(∑j1if[v][j])f[u][i]\prod\limits_{v\in son_u}(\sum\limits_{j1}^{i}f[v][j])f[u][i]v∈sonu​∏​(j1∑i​f[v][j]) 前缀和优化&#xff1a; 设g[u…

【dfs】益智游戏(2017 特长生 T2)

题目大意 给你四个数字&#xff0c;问你能否经过加减乘除使其结果为24 解题思路 先暴力枚举四个数字的全排列&#xff0c;然后枚举运算符和括号 代码 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long …

分布式系统消息中间件——RabbitMQ的使用基础篇

前言我是在解决分布式事务的一致性问题时了解到RabbitMQ的&#xff0c;当时主要是要基于RabbitMQ来实现我们分布式系统之间对有事务可靠性要求的系统间通信的。关于分布式事务一致性问题及其常见的解决方案&#xff0c;可以看我另一篇博客。提到RabbitMQ&#xff0c;不难想到的…

P4630-[APIO2018]Duathlon铁人两项【圆方树】

正题 题目链接:https://www.luogu.com.cn/problem/P4630 题目大意 nnn个点mmm条边的一张无向图&#xff0c;求有多少对三元组(s,c,f)(s,c,f)(s,c,f)满足s≠f≠ts\neq f\neq ts​f​t且存在一条从sss到fff的简单路径经过ccc 解题思路 一个比较显然的结论是在一个点双中的三…

小a的旅行计划

来源&#xff1a;牛客网 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言65536K 64bit IO Format: %lld文章目录题目描述题解&#xff1a;代码&#xff1a;题目描述 小a终于放假了&#xff0c;它想在假期中去一些地方…

吃豆人(luogu 7472/NOI Online 2021 普及组 T2)

正题 luogu 7472 题目大意 给出一个正方形点阵&#xff0c;让你选择两个点&#xff0c;分别向两个方向移动&#xff08;必须是45度&#xff09;&#xff0c;每到一个点就得到该点的贡献&#xff08;不重复得&#xff09;&#xff0c;遇到墙壁反射&#xff0c;问你最大贡献 解…

[XSY] 选举(线段树优化dp)

选举 //a[i]1 or 0 or -1,表示i支持小奇 or 中立 or 支持魔法猪 //sum[i]a[1]a[2]...a[i] //设dp[i]表示把1~i划分成若干区间,(小奇得票-魔法猪得票)的最大值 /*dp[i]max {dp[j]1 (sum[i]-sum[j]>0即sum[i]>sum[j])dp[j] (sum[i]-sum[j]0即sum[i]sum[j])dp[j]-1 (sum[…

P3480-[POI2009]KAM-Pebbles【阶梯博弈】

正题 题目链接:https://www.luogu.com.cn/problem/P3480 题目大意 nnn个石头堆上进行Nim\text{Nim}Nim游戏&#xff0c;不过需要满足每次操作前后都有ai≤ai1(i∈[1,n))a_i\leq a_{i1}(\ i\in[1,n)\ )ai​≤ai1​( i∈[1,n) ) 解题思路 让每一个biai−ai−1b_ia_i-a_{i-1}bi​…

在 Centos7 用Jexus服务器 运行.Net Core 只需几步

安装 .Net SDK 不需要按照 .net core runtime,sdk 依赖于运行时会自动安装第一步 添加dotnet源sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm第二步 安装 .Net Core可能由于网络原因&#xff0c;下载要耐心等待一段时间,下载完成后…

小球碰撞(理解ing)

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 一个弹球&#xff08;可视为质点&am…

【斜率优化】Cats Transport(luogu-CF 311B)

正题 luogu-CF 311B 题目大意 有n个点&#xff0c;p个铲屎官和m只猫 did_idi​表示i到i-1的距离 第i只猫在tit_iti​这个时间hih_ihi​这个点开始等待铲屎官来接它走 铲屎官会以一个单位时间走一个单位长度的速度从第一个点向最后一个点走&#xff08;不能停止&#xff09;&a…

[XSY4170] 妹子(线段树上二分)

传送门 题意&#xff1a; 给出两个长度为NNN的整数序列A1A2...ANA_1A_2...A_NA1​A2​...AN​,B1B2...BNB_1B_2...B_NB1​B2​...BN​。有MMM组询问(opt,l,r,d)(opt,l,r,d)(opt,l,r,d)&#xff0c;令nr−l1nr-l1nr−l1 若optAoptAoptA&#xff1a;∀i∈[1,n],aiAli−1d,biBli−…

P3643-[APIO2016]划艇【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P3643 题目大意 求有多少个nnn个数的序列xxx满足&#xff0c;xi∈{0}∪[ai,bi]x_i\in \{0\}\cup[a_i,b_i]xi​∈{0}∪[ai​,bi​]且非000数递增。 解题思路 会发现ai,bia_i,b_iai​,bi​很大不能太暴力的将第二维的dpdpdp设…