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

https://www.cnblogs.com/lwqlun/p/9671611.html

背景介绍

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

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

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

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

BenchmarkDotNet

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控制台程序。

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

PM> Install-Package BenchmarkDotNet

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

public class Program
{
public class SingleVsFirst
{
private readonly List<string> _haystack = new List<string>();
private readonly int _haystackSize = 1000000;
private readonly string _needle = "needle"; public SingleVsFirst()
{
//Add a large amount of items to our list.
Enumerable.Range(1, _haystackSize).ToList().ForEach(x => _haystack.Add(x.ToString()));
//Insert the needle right in the middle.
_haystack.Insert(_haystackSize / 2, _needle);
} [Benchmark]
public string Single() => _haystack.SingleOrDefault(x => x == _needle); [Benchmark]
public string First() => _haystack.FirstOrDefault(x => x == _needle); } public static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<SingleVsFirst>();
Console.ReadLine();
}
}

代码解释说明

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

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

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

代码中的Single和First方法,分别调用了Linq to object的SingleOrDefault和FirstOrDefault方法来查询字符串集合中的"needle"字符串。

在Single和First方法上,我们加入[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个方法处理的平均响应时间,First比Single快了一倍(这和我们测试字符串放置的位置有关系)。

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

BenchmarkDotNet中我们还可以使用[ParamsSource]参数来指定测试的用例范围。

在上面的代码中,我们测试了匹配字符串在集合中间位置时,First和Single的效率对比,下面我们修改上面的代码,我们希望分别测试匹配字符串在集合头部,尾部以及中间位置时First和Single的效率对比。

using System;

using System.Collections.Generic;

using System.Linq;

using BenchmarkDotNet.Attributes;

using BenchmarkDotNet.Running;

namespace BenchmarkExample

{

public class SingleVsFirst

{

private readonly List _haystack = new List();

private readonly int _haystackSize = 1000000;

    public List<string> _needles => new List<string> { "StartNeedle", "MiddleNeedle", "EndNeedle" };

    public SingleVsFirst()
{
//Add a large amount of items to our list.
Enumerable.Range(1, _haystackSize).ToList().ForEach(x => _haystack.Add(x.ToString())); //One at the start.
_haystack.Insert(0, _needles[0]);
//One right in the middle.
_haystack.Insert(_haystackSize / 2, _needles[1]);
//One at the end.
_haystack.Insert(_haystack.Count - 1, _needles[2]);
} [ParamsSource(nameof(_needles))]
public string Needle { get; set; } [Benchmark]
public string Single() => _haystack.SingleOrDefault(x => x == Needle); [Benchmark]
public string First() => _haystack.FirstOrDefault(x => x == Needle); } class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<SingleVsFirst>();
Console.ReadLine();
}
}

}

代码解释说明

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

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

我们添加了一个属性Needle, 表示当前测试的用例,在被测试Single和First方法中,我们使用属性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解析库中,我们使用了以下代码

[MemoryDiagnoser]
public class CsvBenchmarking
{
[Benchmark(Baseline =true)]
public IEnumerable<Automobile> CSVHelper()
{
TextReader reader = new StreamReader("import.txt");
var csvReader = new CsvReader(reader);
var records = csvReader.GetRecords<Automobile>();
return records.ToList();
} [Benchmark]
public IEnumerable<Automobile> TinyCsvParser()
{
CsvParserOptions csvParserOptions = new CsvParserOptions(true, ',');
var csvParser = new CsvParser<Automobile>(csvParserOptions, new CsvAutomobileMapping()); var records = csvParser.ReadFromFile("import.txt", Encoding.UTF8); return records.Select(x => x.Result).ToList();
}
}

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

    Method |       Mean | Scaled | Allocated |

-------------- |-----------

性能测试工具BenchmarkDotnet的更多相关文章

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

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

  2. .NET平台性能测试工具BenchmarkDotnet 简介[译文]

    项目中需要用到性能测试,发现.net 平台的这个神器. 觉得很不错,接下来准备做个系列.具体参考官方介绍 做基线对比测试不是那么容易,你很容易就翻车掉坑里,BenchmarkDotNet 会帮你避坑( ...

  3. 性能测试工具 wrk 安装与使用

    介绍 今天给大家介绍一款开源的性能测试工具 wrk,简单易用,没有Load Runner那么复杂,他和 apache benchmark(ab)同属于性能测试工具,但是比 ab 功能更加强大,并且可以 ...

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

    .NET Core 超强性能测试组件BenchmarkDotNet 支持Full .NET Framework, .NET Core (RTM), Mono. BenchmarkDotNet支持 C# ...

  5. 性能测试工具Locust

    An open source load testing tool. 一个开源性能测试工具. define user behaviour with python code, and swarm your ...

  6. 给CentOS6.3 + PHP5.3 安装PHP性能测试工具 XHProf-0.9.2

    一.什么是XHProf XHProf官网:http://pecl.php.net/package/xhprof XHProf是一个分层PHP性能分析工具.它报告函数级别的请求次数和各种指标,包括 阻塞 ...

  7. Android性能测试工具APT使用指南

    腾讯的安卓平台高效的性能测试工具APT(Android Performance Testing Tools),适用于开发自测和定位性能瓶颈,帮助测试人员完成性能基准测试.竞品测试. APT提供了CPU ...

  8. 安卓性能测试工具-GT,安测试

    GT: 是腾讯出品的一款APP的随身调测平台,它是直接运行在手机上的“集成调测环境”(IDTE,  Integrated  Debug&Test  Environment).利用GT,仅凭一部 ...

  9. TCP/UDP网络性能测试工具 - Netperf (zz) ..网络测试工具

    在构建或管理一个网络系统时,我们更多的是关心网络的可用性,即网络是否连通,而对于其整体的性能往往考虑不多. 除了netperf以外.       还有很多其它的网络性能测试工具.       如db, ...

随机推荐

  1. 字典树 trie树 学习

    一字典树 字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种   二.性质 根节点不包含字符,除根节点以外的每一个节点都只包含一个字符: 从根节点到某一节点,路径上经过的字符串连接起 ...

  2. iOS 52个技巧学习心得笔记 第二章 对象 , 消息, 运行期

    1. 属性 在开发过程中经常要用到定义属性,@property和@synthesize是经常用到的属性, property在.h文件中作声明,@synthesize在.m文件中用于实现 // Stud ...

  3. C# XMLHttpRequest对象—Ajax实例

    Get: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> ...

  4. $SublimeText2常用快捷键

    1.删除一行:ctrl + shift + K2.替换:ctrl + H3.设置书签:Ctrl+F2设置书签F2 下一个书签Shift+F2上一个书签4.查找:ctrl + F 查找F3 查找下一个s ...

  5. uart测试代码

    #include <stdio.h> /*标准输入输出定义*/ #include <stdlib.h> /*标准函数库定义*/ #include <unistd.h> ...

  6. Linux环境下的图形系统和AMD R600显卡编程(1)——Linux环境下的图形系统简介

    转:https://www.cnblogs.com/shoemaker/p/linux_graphics01.html Linux/Unix环境下最早的图形系统是Xorg图形系统,Xorg图形系统通过 ...

  7. PHP 最大化资源配置 Resource Limits 错误两则

    报错信息1:PHP Fatal error: Allowed memory size of 25165824 bytes exhausted (tried to allocate 67108888 b ...

  8. 老司机也该掌握的MySQL优化指南

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,所以我们本文会提供一些优化参考,大家可以参考以下步骤来优化: 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运 ...

  9. Ubuntu登陆不进去(已解决)【转】

    本文转载自:https://blog.csdn.net/u010925447/article/details/72236387 Ubuntu一直在登陆界面循环:登陆密码是正确的,但是登陆后自动退回登陆 ...

  10. NorFlash、NandFlash、eMMC比较区别【转】

    本文转载自:http://www.veryarm.com/1200.html 快闪存储器(英语:Flash Memory),是一种电子式可清除程序化只读存储器的形式,允许在操作中被多次擦或写的存储器. ...