.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集合天生线程安全,可以不用加锁直接遍历,不仅性能更加优异,代码也更加优雅,能帮助我们快速实现稳定高效的程序。
.Net中的不可变集合(Immutable Collection)简介的更多相关文章
- 不可变集合 Immutable Collections
例子 public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( "red", &q ...
- Java中的不可变集合,我们换个方式理解!!!
不可变集合例: public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( "red" ...
- JavaScript 中的不可变对象(Immutable Objects)
默认情况下,JavaScript 中的对象是可变的.我们可以更改原始值(字符串,数字等)和对象.我们来看看这个对象: let obj = { num: , obj: { content: " ...
- Guava集合--Immutable(不可变)集合
所谓不可变集合,顾名思义就是定义了之后不可修改的集合. 一.为什么要使用不可变集合 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态 ...
- [Guava官方文档翻译] 7. Guava的Immutable Collection(不可变集合)工具 (Immutable Collections Explained)
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3538666.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...
- Guava学习笔记:Immutable(不可变)集合
不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 1.对不可靠的客 ...
- Immutable(不可变)集合
Immutable(不可变)集合 不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对 ...
- java代码之美(4)---guava之Immutable(不可变)集合
Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...
- 牛客网Java刷题知识点之Java 集合框架的构成、集合框架中的迭代器Iterator、集合框架中的集合接口Collection(List和Set)、集合框架中的Map集合
不多说,直接上干货! 集合框架中包含了大量集合接口.这些接口的实现类和操作它们的算法. 集合容器因为内部的数据结构不同,有多种具体容器. 不断的向上抽取,就形成了集合框架. Map是一次添加一对元素. ...
随机推荐
- docker 踩坑笔记之 psql: could not connect to server
最近在用docker跑rails,也遇到了一些坑,这里记录一下. 首先build项目: docker-compose build 然后就开始报错了: psql: could not connect t ...
- Python保护变量、私有变量、私有方法
保护变量.私有变量.私有方法介绍: _xxx: 单下划线开头叫保护变量,意思是只有类对象和子类对象自己能访问到这些变量,此变量不能通过from XXX import xxx 导入: __xxx : 双 ...
- 团队Alpha版本冲刺(六)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- c++ devived object model
单一虚函数继承 class A{public: virtual int foo( ) { return val ; } virtual int funA( ) {}private: int val ; ...
- atan与atan2的区别
相比较ATan,ATan2究竟有什么不同?本篇介绍一下ATan2的用法及使用条件. 对于tan(θ) = y / x: θ = ATan(y / x)求出的θ取值范围是[-PI/2, PI/2]. θ ...
- 内存cgroup
内存cgroup的值都是从哪里来的呀 page_counter_charge是增加page_counter的计数, try_charge函数和mem_cgroup_migrate函数是增加普通进程内存 ...
- Dictionary & Chinese
Dictionary & Chinese DC & dict https://github.com/zollero/simplified-chinese https://github. ...
- jQuery中Ajax的属性设置
1.全局设置为同步 $.ajaxSetup({ async: false });
- 一步步制作RPM包
一步步制作RPM包 来源 http://blog.51cto.com/laoguang/1103628 一.RPM制作步骤 我们在企业中有的软件基本都是编译的,我们每次安装都得编译,那怎么办呢?那就根 ...
- Codeforces 835 F Roads in the Kingdom(树形dp)
F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...