.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是一次添加一对元素. ...
随机推荐
- sql分页汇总-摘抄自网络
文章:几种常见SQL分页方式效率比较 个人倾向于:(2005以上版本支持 row_number()) select * from ( select row_number()over(order by ...
- zkCli.sh客户端其他命令简介
quit 退出 connect host:port 连接到其他ZooKeeper服务器 close 关闭连接 history 操作指令历史 redo 重复执行某个指令, 使用格式为 redo id, ...
- POJ 2983-Is the Information Reliable
Description The galaxy war between the Empire Draco and the Commonwealth of Zibu broke out 3 years a ...
- P4285 [SHOI2008]汉诺塔
题目描述 汉诺塔由三根柱子(分别用A.B.C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操作是指:从一根 ...
- [洛谷P4726]【模板】多项式指数函数
题目大意:给出$n-1$次多项式$A(x)$,求一个 $\bmod{x^n}$下的多项式$B(x)$,满足$B(x) \equiv e^{A(x)}$. 题解:(by Weng_weijie) 泰勒展 ...
- [CF1000E]We Need More Bosses
题目大意:给一张无向图,要求找一对$s$和$t$,使得其路径上的割边是最多的,输出其数量. 题解:把边双缩点以后求树的直径. 卡点:无 C++ Code: #include <cstdio> ...
- 50 days before NOI2017
2017.5.31 今天开了这个博客,打算每天来写点东西,嗯...毕竟要NOI了嘛... 第一天跑到常州里集训,打开题目一看湖南集训题... T1刷一下写完,然后交了然后发现错了...赶紧改过来,大概 ...
- python任意编码转utf8或者unicode
# encoding: utf-8 ''' Created on 2015年2月8日 @author: 张鹏程 aprial@163.com @copyright: 版权所有, 尊重劳动成功, 转载与 ...
- OpenGL入门学习 教程 (五)三维的空间变换
http://oulehui.blog.163.com/blog/static/796146982011924428755/ 在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从 ...
- [转]Google 的开源技术protobuf 简介与例子
本文来自CSDN博客:http://blog.csdn.NET/program_think/archive/2009/05/31/4229773.aspx 今天来介绍一下“Protocol Buffe ...