您当前的位置: 首页 >  性能优化

寒冰屋

暂无认证

  • 3浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

.NET性能优化-快速遍历List集合

寒冰屋 发布时间:2022-08-19 19:30:00 ,浏览量:3

目录

简介

遍历方式

使用foreach语句

使用List的ForEach方法

for循环遍历

使用CollectionsMarshal

总结

附录

 

简介

System.Collections.Generic.List是.NET中的泛型集合类,可以存储任何类型的数据,因为它的便利和丰富的API,在我们平时会广泛的使用到它,可以说是使用最多的集合类。

在代码编写中,我们经常需要遍历一个List集合,获取里面的得元素进行一些业务的处理。通常情况下,集合内的元素不是很多,遍历起来非常快。但是对于一些大数据处理,统计,实时计算等动辄数万、十万数据的List集合,如何快速的遍历它呢?这就是今天需要和大家分享的内容。

遍历方式

我们来看看不同遍历方式的性能表现,构建了如下一个性能基准测试,使用不同数量级的集合遍历来看看不同方式的性能表现。代码片段如下所示:

public class ListBenchmark
{
    private List _list = default!;

    // 分别测试10、1千、1万、10万及100万数据时的表现
    [Params(10, 1000, 1_0000, 10_0000, 100_0000)]
    public int Size { get; set; }

    [GlobalSetup]
    public void Setup()
    {
        // 提前创建好数组
        _list = new List(Size);
        for (var i = 0; i  { });  
}

它是List内部实现的方法,所以能直接访问私有数组,另外能避免掉溢出检查;按照理论上来说它应该会很快速;但是在我们的场景中只有一个空方法,可能表现并不会有完全内联调用的foreach方法好。下面是ForEach方法的源码,可以看到它没有了溢出检查,不过还保留了并发的版本号检查。

另外由于需要给ForEach方法传递委托,所以在调用代码中,每一次都会检查闭包生成类中的委托对象是否为空,如果不为空则new Action(),如下所示:我们来看看它与foreach关键字相比性能上有什么差别吧。下图是基准测试的结果:从测试结果来看,要比直接使用foreach关键字慢40%,看来如非必要,直接使用foreach是比较好的选择,那么还有没有什么更快的方式呢?

for循环遍历

回到了我们最古老的方式,就是使用for关键字来遍历集合。它应该是目前来说性能最好的遍历方式,因为它不需要像之前的那几种方式一样有一些多余的代码(不过索引器同样有检查,防止溢出),另外很显然它不会检查版本号,所以在多线程环境下集合被改变,使用for不会有异常抛出。测试代码如下所示:

public void For()  
{  
    for (var i = 0; i             
关注
打赏
1665926880
查看更多评论
0.0547s