.Net中的不可變集合(Immutable Collection)程序集簡介
今天發(fā)現(xiàn)MS在Nuget上發(fā)布了一個Immutable Collection的程序集,提供了對不可變對象的集合的支持。
簡單的看了一下,貌似支持的還比較全:
ImmutableArray<T>
ImmutableStack<T>
ImmutableQueue<T>
ImmutableList<T>
ImmutableHashSet<T>
ImmutableSortedSet<T>
ImmutableDictionary<K, V>
ImmutableSortedDictionary<K, V>
使用方式比較簡單,一個簡單的示例如下(對對Immutable特性不熟悉的朋友請注意輸出結(jié)果和List的區(qū)別):
var color1 = ImmutableArray.Create("orange", "red", "blue"); var color2 = color1.Add("black"); Console.WriteLine(">>> color1: " + color1); Console.WriteLine(">>> color2: " + color2);
Immutable Builders
由于Immutable對象的更改操作是生成你一個新的對象,因此當頻繁更改時,開銷是比較大的。因此,和傳統(tǒng)的Immutable對象string有一個StringBuild一樣,對于Immutable集合,也提供了相應(yīng)的Immutable Builder對象來進行批量更新操作。
為了方便使用,還提供了兩個擴展函數(shù)ToBuilder()和ToImmutable()在Immutable Builder和Immutable集合間快速互相轉(zhuǎn)換。
var color2Builder = color1.ToBuilder(); color2Builder.Add("black"); color2Builder.Add("white"); var color2 = color2Builder.ToImmutable();
性能
下表是MS給出的基本集合操作的性能,還是令人滿意的。具體的數(shù)據(jù)結(jié)構(gòu)暫時沒有時間去研究它,感覺大部分應(yīng)該都是樹。
| 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) |
不過,由于每次對集合操作都會生成新的副本(并不會拷貝集合成員),應(yīng)該是有額外的內(nèi)存開銷的,從它的性能上來看,應(yīng)該是一種空間換時間的做法,有空再研究一下。
使用場景
Immutable由于具有不可變性,天生是線程安全的,因此非常適宜于多線程場景。例如,在遍歷的時候,為了防止遍歷期間集合被破壞,傳統(tǒng)的做法有如下兩種
1. 鎖定法:
lock (list) { foreach (var item in list) { //do something } }
如果遍歷的時間較長,會長期鎖定集合,導(dǎo)致其它的調(diào)用處餓死。為了解決這種情況,又有下一種做法。
2. 副本法
lock (list) { var listCopy = list.ToArray(); } foreach (var item in listCopy) { //do something }
這種方式的最大問題是每次遍歷都要生成副本,如果遍歷比較頻繁則開銷較大。PS:這種場景下仍然需要lock(生成副本的時候)。
另外,這兩種地方都需要對對象加鎖,加鎖除了影響性能外,還需要在每一個使用的地方都加鎖,并且還需要避免死鎖。這個基本上和內(nèi)存泄漏一樣對程序員來說是是一個非常大的負擔
而Immutable集合天生線程安全,可以不用加鎖直接遍歷,不僅性能更加優(yōu)異,代碼也更加優(yōu)雅,能幫助我們快速實現(xiàn)穩(wěn)定高效的程序。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
那些年,我還在學(xué)習(xí)asp.net(二) 學(xué)習(xí)筆記
那些年覺得看視頻是很輕松的了解一個東西,但是這樣的不足就是感覺太慢了,沒有看書來得快,所以在有了一些了解后,還得看點書,也許書上的不一定好,但書上會把每一個應(yīng)該說到的地方說到,好有個初步的認識2012-03-03ABP框架的體系結(jié)構(gòu)及模塊系統(tǒng)講解
ABP框架是基于ASP.NET的Web開發(fā)框架,不過它遵循一種名為DDD(領(lǐng)域驅(qū)動設(shè)計)的設(shè)計模式原則,接下來我們就來看一下ABP框架的體系結(jié)構(gòu)及模塊系統(tǒng)講解2016-06-06Asp.net中Request.Url的各個屬性對應(yīng)的意義介紹
網(wǎng)絡(luò)上關(guān)于Request.Url的說明已經(jīng)很多也很豐富了,但是自己還是實踐了一下,看看最終的結(jié)果與網(wǎng)絡(luò)上的是否一致2012-05-05ASP.NET 中 Button、LinkButton和ImageButton 三種控件的使用詳解
本文主要介紹Button、LinkButton和ImageButton 三種控件的使用方法,并一一舉例演示它們的用法,希望對大家有所幫助。2016-04-04