我们之前提到 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/

最新文章

  1. Windows下快速安装Flask的一次经历
  2. java基础学习总结-接口
  3. 浏览器兼容性之JavaScript篇
  4. 又是一个二模02,不过day2
  5. N-gram介绍
  6. MSM8909平台 LED背光的控制
  7. python调用smtplib模块发送邮件
  8. apache asp.net
  9. SKYLINE
  10. ibatisnet框架使用说明
  11. 201521123026 《Java程序设计》第6周学习总结
  12. 关于opencv模板匹配功能的项目测试记录
  13. Thymeleaf3语法详解
  14. Vue系列之 =&gt; 父组件向子组件传值
  15. Linux Capability探索实验
  16. kubernetes 里面pod时间修改
  17. android限制横竖屏切换 方法
  18. 模块化,AMD规范
  19. org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected subelement profile
  20. Java通过继承外部类来建立该外部类的protected内部类的实例(转)

热门文章

  1. windows下mysql的数据主主同步
  2. 使用 Spring Security 手动验证用户
  3. EFCore (二)之 跟踪实体
  4. 2022-08-12-esp32把玩记-②_用Micropython点ssd1306_oled屏幕
  5. Nginx通用优化示例
  6. docker gitlab迁移 备份 部署 搭建以及各种问题
  7. Vue学习之--------深入理解Vuex之多组件共享数据(2022/9/4)
  8. 配置文件yaml和ini
  9. SQL中的转义字符和通配符
  10. 十四、资源控制器之RS