.Net中的不可变集合(Immutable Collection)程序集简介

 更新时间:2022年06月20日 10:30:11   作者:天方  
这篇文章介绍了.Net中的不可变集合(Immutable Collection)程序集,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

今天发现MS在Nuget上发布了一个Immutable Collection的程序集,提供了对不可变对象的集合的支持。

简单的看了一下,貌似支持的还比较全:

  • ImmutableArray<T>

  • ImmutableStack<T>

  • ImmutableQueue<T>

  • ImmutableList<T>

  • ImmutableHashSet<T>

  • ImmutableSortedSet<T>

  • ImmutableDictionary<K, V>

  • ImmutableSortedDictionary<K, V>

使用方式比较简单,一个简单的示例如下(对对Immutable特性不熟悉的朋友请注意输出结果和List的区别):

    var color1 = ImmutableArray.Create("orange", "red", "blue");
    var color2 = color1.Add("black");

    Console.WriteLine(">>> color1: " + color1);
    Console.WriteLine(">>> color2: " + color2);

Immutable Builders

由于Immutable对象的更改操作是生成你一个新的对象,因此当频繁更改时,开销是比较大的。因此,和传统的Immutable对象string有一个StringBuild一样,对于Immutable集合,也提供了相应的Immutable Builder对象来进行批量更新操作。

为了方便使用,还提供了两个扩展函数ToBuilder()和ToImmutable()在Immutable Builder和Immutable集合间快速互相转换。

    var color2Builder = color1.ToBuilder();
    color2Builder.Add("black");
    color2Builder.Add("white");
    var color2 = color2Builder.ToImmutable();

性能

下表是MS给出的基本集合操作的性能,还是令人满意的。具体的数据结构暂时没有时间去研究它,感觉大部分应该都是树。

  

Mutable (amortized)

Mutable (worst case)

Immutable

Stack.Push

O(1)

O(n)

O(1)

Queue.Enqueue

O(1)

O(n)

O(1)

List.Add

O(1)

O(n)

O(log n)

HashSet.Add

O(1)

O(n)

O(log n)

SortedSet.Add

O(log n)

O(n)

O(log n)

Dictionary.Add

O(1)

O(n)

O(log n)

SortedDictionary.Add

O(log n)

O(n log n)

O(log n)

不过,由于每次对集合操作都会生成新的副本(并不会拷贝集合成员),应该是有额外的内存开销的,从它的性能上来看,应该是一种空间换时间的做法,有空再研究一下。

使用场景

Immutable由于具有不可变性,天生是线程安全的,因此非常适宜于多线程场景。例如,在遍历的时候,为了防止遍历期间集合被破坏,传统的做法有如下两种

1. 锁定法:

    lock (list)
    {
        foreach (var item in list)
        {
            //do something
        }
    }

如果遍历的时间较长,会长期锁定集合,导致其它的调用处饿死。为了解决这种情况,又有下一种做法。

2. 副本法

    lock (list)
    {
        var listCopy = list.ToArray();    
    }

    foreach (var item in listCopy)
    {
        //do something
    }

这种方式的最大问题是每次遍历都要生成副本,如果遍历比较频繁则开销较大。PS:这种场景下仍然需要lock(生成副本的时候)。

另外,这两种地方都需要对对象加锁,加锁除了影响性能外,还需要在每一个使用的地方都加锁,并且还需要避免死锁。这个基本上和内存泄漏一样对程序员来说是是一个非常大的负担

而Immutable集合天生线程安全,可以不用加锁直接遍历,不仅性能更加优异,代码也更加优雅,能帮助我们快速实现稳定高效的程序。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 那些年,我还在学习asp.net(二) 学习笔记

    那些年,我还在学习asp.net(二) 学习笔记

    那些年觉得看视频是很轻松的了解一个东西,但是这样的不足就是感觉太慢了,没有看书来得快,所以在有了一些了解后,还得看点书,也许书上的不一定好,但书上会把每一个应该说到的地方说到,好有个初步的认识
    2012-03-03
  • 将.NET 6项目部署到Linux

    将.NET 6项目部署到Linux

    本文详细讲解了将.NET 6项目部署到Linux的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • ABP框架的体系结构及模块系统讲解

    ABP框架的体系结构及模块系统讲解

    ABP框架是基于ASP.NET的Web开发框架,不过它遵循一种名为DDD(领域驱动设计)的设计模式原则,接下来我们就来看一下ABP框架的体系结构及模块系统讲解
    2016-06-06
  • WPF布局及布局容器介绍

    WPF布局及布局容器介绍

    这篇文章介绍了WPF布局及布局容器,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-01-01
  • Asp.net中Request.Url的各个属性对应的意义介绍

    Asp.net中Request.Url的各个属性对应的意义介绍

    网络上关于Request.Url的说明已经很多也很丰富了,但是自己还是实践了一下,看看最终的结果与网络上的是否一致
    2012-05-05
  • ASP.NET Core中的Razor页面使用视图组件

    ASP.NET Core中的Razor页面使用视图组件

    这篇文章介绍了ASP.NET Core中的Razor页面使用视图组件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • .NET中开源文档操作组件DocX的介绍与使用

    .NET中开源文档操作组件DocX的介绍与使用

    在大家日常开发中读写Offic格式的文档,大家多少都有用到,可能方法也很多,组件有很多。这里不去讨论其他方法的优劣,只是向大家介绍一款开源的读写word文档的组件。读写Excel有NPOI,读写Word,那看看DocX吧。下面跟着小编一起来学习学习吧。
    2016-12-12
  • ASP.Net Core MVC基础系列之中间件

    ASP.Net Core MVC基础系列之中间件

    这篇文章介绍了ASP.Net Core MVC的中间件,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-02-02
  • ASP.NET 中 Button、LinkButton和ImageButton 三种控件的使用详解

    ASP.NET 中 Button、LinkButton和ImageButton 三种控件的使用详解

    本文主要介绍Button、LinkButton和ImageButton 三种控件的使用方法,并一一举例演示它们的用法,希望对大家有所帮助。
    2016-04-04
  • ABP框架的基础配置及依赖注入讲解

    ABP框架的基础配置及依赖注入讲解

    这篇文章主要介绍了ABP框架的基础配置及依赖注入讲解,是ABP框架上手使用的基本,要的朋友可以参考下
    2016-06-06

最新评论