我们之前提到 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 的性能的更多相关文章

  1. 为什么要指定HashMap的容量?HashMap指定容量初始化后,底层Hash数组已经被分配内存了吗?

    为什么要指定HashMap的容量? 首先创建HashMap时,指定容量比如1024后,并不是HashMap的size不是1024,而是0,插入多少元素,size就是多少: 然后如果不指定HashMap ...

  2. Docker 指定容量

    vim /etc/sysconfig/docker-storage加入以下命令 DOCKER_STORAGE_OPTIONS="--storage-driver devicemapper - ...

  3. Java:String、StringBuffer和StringBuilder的区别

    1 String String:字符串常量,字符串长度不可变.Java中String是immutable(不可变)的. String类的包含如下定义: /** The value is used fo ...

  4. Java的String、StringBuffer和StringBuilder的区别

    1.String 2.Stringbuffer 3.StringBuilder 4.三者之间的区别 5.使用策略 1.String public final class String implemen ...

  5. String、StringBuffer和StringBuilder的区别

    1 String String:字符串常量,字符串长度不可变.Java中String是immutable(不可变)的. String类的包含如下定义: /** The value is used fo ...

  6. String, StringBuilder, StringBuffer问题

    1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...

  7. 重温java中的String,StringBuffer,StringBuilder类

    不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...

  8. String、StringBuffer、StringBuilder区分和性能比较

    转载自:http://www.cnblogs.com/fancydeepin/archive/2013/04/23/min-snail-speak_String-StringBuffer-String ...

  9. Java中的String、StringBuffer和StringBuilder的区别

    类型  是否可变  线程安全  能否频繁修改  String  不可变  安全  否  StringBuffer  可变  安全  能  StringBuilder  可变  不安全  能 1.可变与 ...

  10. [Java]String、 StringBuffer、StringBuilder的区别

    一.异同点: 1) 都是 final 类, 都不允许被继承; 2) String 长度是不可变的, StringBuffer.StringBuilder 长度是可变的; 3) StringBuffer ...

随机推荐

  1. 内网横向渗透 之 ATT&CK系列一 之 横向渗透域主机

    前言 上一篇文章中已获取了关于域的一些基本信息,在这里再整理一下,不知道信息收集的小伙伴可以看回上一篇文章哦 域:god.org 域控 windows server 2008:OWA,192.168. ...

  2. Java泛型的总结

    泛型可以用于接口.类.方法上.还有泛型通配符这个概念 泛型的好处:可以在编译时检查 1.用于方法中,指定该方法中的形参的类型. 语法:修饰符 <代表泛型的变量> 返回值类型 方法名(参数) ...

  3. 实时营销引擎在vivo营销自动化中的实践 | 引擎篇04

    作者:vivo 互联网服务器团队 本文是<vivo营销自动化技术解密>的第5篇文章,重点分析介绍在营销自动化业务中实时营销场景的背景价值.实时营销引擎架构以及项目开发过程中如何利用动态队列 ...

  4. GO编译时不避免引入外部动态库的解决方法

    简介 最近碰到一个问题,有一个流量采集的组件中使用到了github.com/google/gopacket 这个库,这个库使用一切正常,但是唯独有一个缺点,编译后的二进制文件依赖于libpcap.so ...

  5. 齐博X1-新建一个空模板并在后台选择

    本节实际操作建立一个空模板,并且让后台识别,选择该风格 先在index_style中建立一个目录,命名mystyle并上传我们在mystyle目录中建立一个info.php文件,代码如下:上传后,后台 ...

  6. 项目实战:在线报价采购系统(React +SpreadJS+Echarts)

    小伙伴们对采购系统肯定不陌生,小到出差路费.部门物资采购:大到生产计划.原料成本预估都会涉及到该系统. 管理人员可以通过采购系统减少管理成本,说是管理利器毫不过分,对于采购的效率提升也有极大帮助. 但 ...

  7. 题解 P6745 『MdOI R3』Number

    前言 不知道是不是正解但是觉得挺好理解. 科学计数法 将一个数表示为\(a\times 10^x\) 的形式.其中\(a\leq10\),\(x\) 为整数. \(\sf Solution\) 其实这 ...

  8. 泛化之美 —— C++11 可变参数模板的妙用

    概述 首先这篇文章出自博客园作者:[qicosmos ],我对本文的实例代码进行了学习.思考和整理纠正,理清了文章的全部细节,觉得这是一篇让我受益匪浅的文章.之所以会接触「可变参数模板」这部分的内容, ...

  9. PageRank原理分析

    pagerank是将众多网页看成一个有向图,每个页面就是有向图中的节点.计算每个节点的出度和入度.如果一个网站被大量其他的网页引用,那么他就会有更高的pr分数. 原理 对于所有与节点i相连的节点,用他 ...

  10. CF815D

    模拟赛遇到的题目. 看各位大佬的做法都不是很懂,于是自己一通乱搞搞出来了. 题意 翻译清楚的不能再清楚了 做法 为了方便叙述,我们将每个给出的三元组表示成 \((a_i,b_i,c_i)\),所选的三 ...