.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是一次添加一对元素. ...
随机推荐
- 解决使用vim-go插件时候保存go代码导致设置好的折叠消失的问题
我之前在用vim编辑python代码的时候,折叠的功能都没啥问题 后来在编辑go代码的时候,我发现我一保存,折叠全都消失了,我很费解,就推断跟我使用的插件有关系,因为我保存的时候会触发gofmt插件格 ...
- Python下安装protobuf
1. 下载安装包 2. 解压缩 tar –xzvf protobuf-2.6.1.tar.gz 3. 安装protoc 在python中使用protocbuf需要Protocal Buffer 编译器 ...
- Java 冒泡排序与快速排序的实现
冒泡排序 基本特点 (1)基于交换思想的排序算法 (2)从一端开始,逐个比较相邻的两个元素,发现倒序即交换. (3)一次遍历,一定能将其中最大(小)的元素交换到其最终位置上 排序过程模 ...
- 第二阶段团队冲刺-six
昨天: 完成打印名单的功能. 今天: 合并程序(添加打印txt). 遇到的问题: web.xml中配置url-pattern一直不合适,不知道为什么会影响界面.
- 【bzoj3781】小B的询问 莫队算法
原文地址:http://www.cnblogs.com/GXZlegend/p/6803821.html 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L ...
- 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)\)个圆,圆与圆之间 ...
- BZOJ4032 [HEOI2015]最短不公共子串 【后缀自动机 + 序列自动机 + dp】
题目链接 BZOJ4032 题解 首先膜\(hb\) 空手切神题 一问\(hash\),二问枚举 三问\(trie\)树,四问\(dp\) 南二巨佬神\(hb\) 空手吊打自动机 \(orz orz ...
- oracle怎么查看一个表或一个索引占用多少空间
很多时候我们想知道一个表或一个索引占用多少M的空间,以下脚本就是满足这个要求的,记住替换其中的内容. SELECT owner, segment_name, SUM(bytes)/1024/1024 ...
- 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 ...
- 【转】shell脚本写的俄罗斯方块游戏
亲测一个很好玩的shell脚本写的俄罗斯方块游戏,脚本来自互联网 先来讲一下思维流程 一.方块的表示 由于shell不能定义二维数组,所以只能用一维数组表示方块,俄罗斯方块主要可以分为7类,每一类方块 ...