使用 BenchmarkDotNet 比较指定容量的 List 的性能
我们之前提到 List 是 .NET 中常用的数据结构,其在存储大量数据时,如果能够指定它的初始化容量,就会有性能提升。这个优化的方法并不是很明显,因此本文将使用 BenchmarkDotNet 库,通过定量对比的方式来证明这一点。
实验过程
引入 BenchmarkDotNet
首先,我们需要在项目中引入 BenchmarkDotNet 库。这可以通过在项目的 NuGet 包管理器中搜索并安装 BenchmarkDotNet 来实现。
指定需要测试的方法和参数
接下来,我们需要指定需要测试的方法和参数。这可以通过在代码中使用 [Benchmark] 属性来实现。例如,我们可以在测试类中定义两个测试方法,一个使用指定容量的 List,一个使用未指定容量的 List。
public class ListBenchmark
{
[Benchmark]
public void ListWithCapacity()
{
var list = new List<int>(1000000);
for (int i = 0; i < 1000000; i++)
{
list.Add(i);
}
}
[Benchmark]
public void ListWithoutCapacity()
{
var list = new List<int>();
for (int i = 0; i < 1000000; i++)
{
list.Add(i);
}
}
}
我们还可以使用其他参数来指定测试的一些细节,如使用的 .NET 框架版本,是否进行内存测量等。
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
[MemoryDiagnoser]
public class ListBenchmark
{
[Benchmark]
public void ListWithCapacity()
{
var list = new List<int>(1000000);
for (int i = 0; i < 1000000; i++)
{
list.Add(i);
}
}
[Benchmark]
public void ListWithoutCapacity()
{
var list = new List<int>();
for (int i = 0; i < 1000000; i++)
{
list.Add(i);
}
}
}
运行测试
最后,我们可以使用 BenchmarkRunner 类来运行测试。这可以通过在 Main 方法中调用 BenchmarkRunner.Run<T>() 方法来实现。其中 T 是包含测试方法的类的类型。
class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<ListBenchmark>();
}
}
实验结果
运行测试后,我们可以得到若干个指标的测试结果。这些指标可能包括运行时间、内存使用量等。通过对比这些指标,我们可以得出结论:使用指定容量的 List 性能优于未指定容量的 List。
例如,我们可以看到,使用指定容量的 List 的平均运行时间要比未指定容量的 List 少得多,内存使用量也更少。
// * Summary * BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22000.1335/21H2)
12th Gen Intel Core i7-12700, 1 CPU, 20 logical and 12 physical cores
.NET SDK=7.0.101
[Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
.NET 7.0 : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
.NET Core 3.1 : .NET Core 3.1.32 (CoreCLR 4.700.22.55902, CoreFX 4.700.22.56512), X64 RyuJIT AVX2 | Method | Job | Runtime | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
|-------------------- |-------------- |-------------- |---------:|----------:|----------:|---------:|---------:|---------:|----------:|
| ListWithCapacity | .NET 7.0 | .NET 7.0 | 1.392 ms | 0.0302 ms | 0.0891 ms | 164.0625 | 164.0625 | 164.0625 | 3.81 MB |
| ListWithoutCapacity | .NET 7.0 | .NET 7.0 | 2.602 ms | 0.0503 ms | 0.0559 ms | 507.8125 | 500.0000 | 500.0000 | 8 MB |
| ListWithCapacity | .NET Core 3.1 | .NET Core 3.1 | 1.168 ms | 0.0227 ms | 0.0278 ms | 218.7500 | 218.7500 | 218.7500 | 3.81 MB |
| ListWithoutCapacity | .NET Core 3.1 | .NET Core 3.1 | 2.652 ms | 0.0520 ms | 0.0461 ms | 507.8125 | 500.0000 | 500.0000 | 8 MB |
总结
本文通过 BenchmarkDotNet 库,使用定量对比的方式,证明了使用指定容量的 List 性能优于未指定容量的 List。这是因为指定容量的 List 在初始化时,会为其分配指定大小的内存空间,而未指定容量的 List 则会在添加元素时,根据需要动态分配内存空间。因此,使用指定容量的 List 可以减少内存分配的次数,从而提升性能。
参考资料
- BenchmarkDotNet[1]
本文采用 Chat OpenAI 辅助注水浇筑而成,如有雷同,完全有可能。
- 本文作者: newbe36524
- 本文链接: https://www.newbe.pro/ChatAI/How-to-use-benchmark-to-compare-performance-about-list-with-capacity-specified/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
参考资料
[1]
BenchmarkDotNet: https://benchmarkdotnet.org/
使用 BenchmarkDotNet 比较指定容量的 List 的性能的更多相关文章
- 为什么要指定HashMap的容量?HashMap指定容量初始化后,底层Hash数组已经被分配内存了吗?
为什么要指定HashMap的容量? 首先创建HashMap时,指定容量比如1024后,并不是HashMap的size不是1024,而是0,插入多少元素,size就是多少: 然后如果不指定HashMap ...
- Docker 指定容量
vim /etc/sysconfig/docker-storage加入以下命令 DOCKER_STORAGE_OPTIONS="--storage-driver devicemapper - ...
- Java:String、StringBuffer和StringBuilder的区别
1 String String:字符串常量,字符串长度不可变.Java中String是immutable(不可变)的. String类的包含如下定义: /** The value is used fo ...
- Java的String、StringBuffer和StringBuilder的区别
1.String 2.Stringbuffer 3.StringBuilder 4.三者之间的区别 5.使用策略 1.String public final class String implemen ...
- String、StringBuffer和StringBuilder的区别
1 String String:字符串常量,字符串长度不可变.Java中String是immutable(不可变)的. String类的包含如下定义: /** The value is used fo ...
- String, StringBuilder, StringBuffer问题
1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...
- 重温java中的String,StringBuffer,StringBuilder类
不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...
- String、StringBuffer、StringBuilder区分和性能比较
转载自:http://www.cnblogs.com/fancydeepin/archive/2013/04/23/min-snail-speak_String-StringBuffer-String ...
- Java中的String、StringBuffer和StringBuilder的区别
类型 是否可变 线程安全 能否频繁修改 String 不可变 安全 否 StringBuffer 可变 安全 能 StringBuilder 可变 不安全 能 1.可变与 ...
- [Java]String、 StringBuffer、StringBuilder的区别
一.异同点: 1) 都是 final 类, 都不允许被继承; 2) String 长度是不可变的, StringBuffer.StringBuilder 长度是可变的; 3) StringBuffer ...
随机推荐
- 【Python+C#】手把手搭建基于Hugging Face模型的离线翻译系统,并通过C#代码进行访问
前言:目前翻译都是在线的,要在C#开发的程序上做一个可以实时翻译的功能,好像不是那么好做.而且大多数处于局域网内,所以访问在线的api也显得比较尴尬.于是,就有了以下这篇文章,自己搭建一套简单的离线翻 ...
- 生产管理ERP哪一款比较好?
生产管理用的是MES,企业管理用的才是ERP,这个得弄清楚!如果要谈生产管理,每家工厂的区别.差异性更大,在工厂甲用得很好的管理系统搬到工厂乙,大概率水土不服,不是软件本身的问题,而是生产的产品.部件 ...
- NOIP2015 普及组 洛谷P2671 求和 (数学)
一道数学题...... 采用分组的思想,我们要统计答案的数对满足两个条件:同奇偶,同颜色.所以可以按这两个要求分组. 然后就是分组处理了,对于每组(有k个数),这里面的任意两对数都是满足条件的,可推出 ...
- windows C++ call ADB command
提供两种方式: 1.Windows API 2.Windows _popen // ADBHelper.cpp : This file contains the 'main' function. Pr ...
- 2022年最新最详细在IDEA中配置Tomcat(含有详细图解过程)、建立使用IEDA建立一个Web项目的案例
1.首先已经成功安装过tomcat 如果没有成功安装,参考这篇tomcat安装教程(安装成功可忽略):https://blog.csdn.net/weixin_43304253/article/det ...
- 齐博x1直播神器聊天小插件
下载地址如下:https://down.php168.com/livemsg.rar 本插件由论坛网友笨熊提供 非常感谢他给大家提供那么一个非常好用的直播必备神器. 如下图所示,大家在直播的时候,这个 ...
- golang开发一个简单的grpc
0.1.索引 https://waterflow.link/articles/1665674508275 1.什么是grpc 在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的 ...
- 《HelloGitHub》第 79 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...
- 题解UVA10948 The primary problem
前言 前置 \(\sf{Solution}\) 既然有了 \(n\) ,那找出 \(a\) 和 \(b\) 就只要枚举 \(a\) 的范围 \(1\sim n\),判断 \(a\) 和 \(n-a\) ...
- 基于LZO的高性能无损数据压缩IP
LZOAccel-C LZO Data Compression Core/无损数据压缩IP Core LZOAccel-C是一个无损数据压缩引擎的FPGA硬件实现,兼容LZO 2.10标准. Core ...