.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特性不熟悉的朋友請注意輸出結果和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集合,也提供了相應的Immutable Builder對象來進行批量更新操作。
為了方便使用,還提供了兩個擴展函數(shù)ToBuilder()和ToImmutable()在Immutable Builder和Immutable集合間快速互相轉換。
var color2Builder = color1.ToBuilder();
color2Builder.Add("black");
color2Builder.Add("white");
var color2 = color2Builder.ToImmutable();性能
下表是MS給出的基本集合操作的性能,還是令人滿意的。具體的數(shù)據(jù)結構暫時沒有時間去研究它,感覺大部分應該都是樹。
| 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由于具有不可變性,天生是線程安全的,因此非常適宜于多線程場景。例如,在遍歷的時候,為了防止遍歷期間集合被破壞,傳統(tǒng)的做法有如下兩種
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集合天生線程安全,可以不用加鎖直接遍歷,不僅性能更加優(yōu)異,代碼也更加優(yōu)雅,能幫助我們快速實現(xiàn)穩(wěn)定高效的程序。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
ASP.NET中 ObjectDataSource控件的DataObjectTypeName屬性
本文主要介紹ObjectDataSource控件和DataObjectTypeName屬性的用法,希望能給小伙伴們一些幫助。2016-04-04
.net?6精簡版webapi教程及熱重載、代碼自動反編譯演示
這篇文章介紹了.net?6精簡版webapi教程及熱重載、代碼自動反編譯演示,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-12-12
SQL Server 2005安裝過程中出現(xiàn)錯誤的解決辦法
SQL Server 2005安裝過程中出現(xiàn)錯誤的解決辦法...2007-02-02
WPF使用ValidationRules對MVVM架構數(shù)據(jù)驗證
這篇文章介紹了WPF使用ValidationRules對MVVM架構數(shù)據(jù)驗證的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-01-01

