.net中的Span<T>類和Memory<T>類介紹
.net core 2.1的重頭戲就是性能,其中最重要的兩個類就是span和memory,本文這里簡單的介紹一下這兩個類的使用。
什么是 Span<T>
Span<T> 是新一種新值類型。它表示一段連續(xù)的區(qū)域,它通常和數(shù)組關(guān)聯(lián),表示數(shù)組中的一部分內(nèi)存。
var arr =?new?byte[10]; Span<byte>?bytes?=?arr;
也可以取數(shù)組中的一部分:
var?bytes?=?new?Span<byte>(arr,?3,?5);
初一乍看,span<T>和ArraySegment<T>非常類似,但span更加強大得多,它不但能用于分離數(shù)組,還可以引用棧上的數(shù)據(jù)。
Span<byte>?bytes?=?stackalloc?byte[2];
也可以引用指針數(shù)據(jù),
Span<byte>?bytes; unsafe?{?bytes?=?new?Span<byte>((byte*)ptr,?1);?}
另外,span還支持 reinterpret_cast 的理念,即可以將 Span<byte> 強制轉(zhuǎn)換為 Span<int>,配合MemoryMarshal類使用,span<T>大多數(shù)的時候都可以代替指針了。
除了功能更加強大外,span在bcl庫中也得到了更多的支持,大多數(shù)支持?jǐn)?shù)組的函數(shù)現(xiàn)在基本上都能直接支持span了,如:
var?inputSpan?=?input.AsSpan(); int?first =?int.Parse(inputSpan.Slice(3,?5));
這個函數(shù)中,int.Parse函數(shù)就能直接支持span,并且由于不產(chǎn)生子字符串,比使用substring的方法性能更高。
另外,系統(tǒng)也支持?jǐn)?shù)組類型到span的隱式轉(zhuǎn)換,同時提供了AsSpan的顯示擴(kuò)展方法,方便將數(shù)組類型轉(zhuǎn)換為span。
除了功能強大外,span的性能也是非常高的,對span的操作基本上和訪問數(shù)組一樣高,無需通過計算來確定指針開頭及其起始偏移,因為"引用"字段本身已對兩者進(jìn)行了封裝。相比之下,ArraySegment<T> 有單獨的偏移字段,這就增加了索引編制和數(shù)據(jù)傳遞操作的成本。
什么是 Memory<T>
Span<T>雖然強大而好用,但它只能存在于棧上,而不能存在于堆上,原因主要有如下兩點:
- span包含"引用"字段(如數(shù)組的開頭),這些引用被稱為"內(nèi)部指針"。對于 .NET 運行時的垃圾回收器,跟蹤這些指針是一項成本相對高昂的操作。因此,運行時將這些引用約束為僅存在于堆棧上,因為它隱式規(guī)定了可以存在的內(nèi)部指針數(shù)量下限。
- 對 Span 執(zhí)行的讀取和寫入操作不是原子操作。如果多個線程同時對 Span 在堆上的字段執(zhí)行讀取和寫入操作,存在"撕裂"風(fēng)險。
這個限制決定了無法將 Span 裝箱,進(jìn)而無法將 Span<T> 與現(xiàn)有反射調(diào)用 API結(jié)合使用,也無法作為泛型參數(shù)。
對于大部分同步處理功能,這個并沒有太大的影響,但由于span<T>無法存儲到堆,從而導(dǎo)致其無法在異步上下文中使用。為了解決這個問題,.net引入了一個新類型Memory<T>。
Memory和span的使用方法大同小異,
var?arr =?new?byte[10]; var?bytes?=?new?Memory<byte>(arr,?3,?5);
不同之處在于 Memory<T> 是不類似引用的結(jié)構(gòu),可以存在于堆上。.net bcl庫對memory也做了很好的支持,如Stream.ReadAsync就能直接支持memory<byte>作為參數(shù)。
另外,也可以從Memory的Span屬性創(chuàng)建指向該Memory的span,這樣也可以使用span的強大的功能。
參考文章:
C# - Span 全面介紹:探索 .NET 新增的重要組成部分
到此這篇關(guān)于.net中Span<T>類和Memory<T>類的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- .NET性能優(yōu)化之為集合類型設(shè)置初始大小的方法
- .NET使用結(jié)構(gòu)體替代類提升性能優(yōu)化的技巧
- asp.net?core實體類生產(chǎn)CRUD后臺管理界面
- .NET設(shè)計模式之UML類圖介紹
- asp.net中Log4.net的工具類helper
- ASP.NET Core應(yīng)用啟動Startup類簡介
- .NET Core中的HttpClientFactory類用法詳解
- .NET Core跨平臺串口通訊使用SerialPortStream基礎(chǔ)類庫問題解決
- .Net?Core應(yīng)用增強型跨平臺串口類庫CustomSerialPort()詳解
相關(guān)文章
.Net中的不可變集合(Immutable Collection)程序集簡介
這篇文章介紹了.Net中的不可變集合(Immutable Collection)程序集,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06.Net創(chuàng)建型設(shè)計模式之原型模式(Prototype)
這篇文章介紹了.Net設(shè)計模式之原型模式(Prototype),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05.Net行為型設(shè)計模式之訪問者模式(Visitor)
這篇文章介紹了.Net行為型設(shè)計模式之訪問者模式(Visitor),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05