今天发现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集合天生线程安全,可以不用加锁直接遍历,不仅性能更加优异,代码也更加优雅,能帮助我们快速实现稳定高效的程序。

.Net中的不可变集合(Immutable Collection)简介的更多相关文章

  1. 不可变集合 Immutable Collections

    例子 public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( "red", &q ...

  2. Java中的不可变集合,我们换个方式理解!!!

    不可变集合例: public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( "red" ...

  3. JavaScript 中的不可变对象(Immutable Objects)

    默认情况下,JavaScript 中的对象是可变的.我们可以更改原始值(字符串,数字等)和对象.我们来看看这个对象: let obj = { num: , obj: { content: " ...

  4. Guava集合--Immutable(不可变)集合

    所谓不可变集合,顾名思义就是定义了之后不可修改的集合. 一.为什么要使用不可变集合 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态 ...

  5. [Guava官方文档翻译] 7. Guava的Immutable Collection(不可变集合)工具 (Immutable Collections Explained)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3538666.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...

  6. Guava学习笔记:Immutable(不可变)集合

    不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 1.对不可靠的客 ...

  7. Immutable(不可变)集合

    Immutable(不可变)集合 不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对 ...

  8. java代码之美(4)---guava之Immutable(不可变)集合

    Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...

  9. 牛客网Java刷题知识点之Java 集合框架的构成、集合框架中的迭代器Iterator、集合框架中的集合接口Collection(List和Set)、集合框架中的Map集合

    不多说,直接上干货! 集合框架中包含了大量集合接口.这些接口的实现类和操作它们的算法. 集合容器因为内部的数据结构不同,有多种具体容器. 不断的向上抽取,就形成了集合框架. Map是一次添加一对元素. ...

随机推荐

  1. 解决使用vim-go插件时候保存go代码导致设置好的折叠消失的问题

    我之前在用vim编辑python代码的时候,折叠的功能都没啥问题 后来在编辑go代码的时候,我发现我一保存,折叠全都消失了,我很费解,就推断跟我使用的插件有关系,因为我保存的时候会触发gofmt插件格 ...

  2. Python下安装protobuf

    1. 下载安装包 2. 解压缩 tar –xzvf protobuf-2.6.1.tar.gz 3. 安装protoc 在python中使用protocbuf需要Protocal Buffer 编译器 ...

  3. Java 冒泡排序与快速排序的实现

    冒泡排序   基本特点 (1)基于交换思想的排序算法  (2)从一端开始,逐个比较相邻的两个元素,发现倒序即交换.      (3)一次遍历,一定能将其中最大(小)的元素交换到其最终位置上 排序过程模 ...

  4. 第二阶段团队冲刺-six

    昨天: 完成打印名单的功能. 今天: 合并程序(添加打印txt). 遇到的问题: web.xml中配置url-pattern一直不合适,不知道为什么会影响界面.

  5. 【bzoj3781】小B的询问 莫队算法

    原文地址:http://www.cnblogs.com/GXZlegend/p/6803821.html 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L ...

  6. Codeforces Round #418 (Div. 2) D. An overnight dance in discotheque

    Codeforces Round #418 (Div. 2) D. An overnight dance in discotheque 题意: 给\(n(n <= 1000)\)个圆,圆与圆之间 ...

  7. BZOJ4032 [HEOI2015]最短不公共子串 【后缀自动机 + 序列自动机 + dp】

    题目链接 BZOJ4032 题解 首先膜\(hb\) 空手切神题 一问\(hash\),二问枚举 三问\(trie\)树,四问\(dp\) 南二巨佬神\(hb\) 空手吊打自动机 \(orz orz ...

  8. oracle怎么查看一个表或一个索引占用多少空间

    很多时候我们想知道一个表或一个索引占用多少M的空间,以下脚本就是满足这个要求的,记住替换其中的内容. SELECT owner, segment_name, SUM(bytes)/1024/1024 ...

  9. Installing Wine 1.5: configure: error: Cannot build a 32-bit program, you need to install 32-bit development libraries(转载)

    Installing Wine 1.5: configure: error: Cannot build a 32-bit program, you need to install 32-bit dev ...

  10. 【转】shell脚本写的俄罗斯方块游戏

    亲测一个很好玩的shell脚本写的俄罗斯方块游戏,脚本来自互联网 先来讲一下思维流程 一.方块的表示 由于shell不能定义二维数组,所以只能用一维数组表示方块,俄罗斯方块主要可以分为7类,每一类方块 ...