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