網(wǎng)站首頁 編程語言 正文
.net core 2.1的重頭戲就是性能,其中最重要的兩個類就是span和memory,本文這里簡單的介紹一下這兩個類的使用。
什么是 Span<T>
Span<T> 是新一種新值類型。它表示一段連續(xù)的區(qū)域,它通常和數(shù)組關聯(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ù)支持數(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)也支持數(shù)組類型到span的隱式轉(zhuǎn)換,同時提供了AsSpan的顯示擴展方法,方便將數(shù)組類型轉(zhuǎn)換為span。
除了功能強大外,span的性能也是非常高的,對span的操作基本上和訪問數(shù)組一樣高,無需通過計算來確定指針開頭及其起始偏移,因為"引用"字段本身已對兩者進行了封裝。相比之下,ArraySegment<T> 有單獨的偏移字段,這就增加了索引編制和數(shù)據(jù)傳遞操作的成本。
什么是 Memory<T>
Span<T>雖然強大而好用,但它只能存在于棧上,而不能存在于堆上,原因主要有如下兩點:
- span包含"引用"字段(如數(shù)組的開頭),這些引用被稱為"內(nèi)部指針"。對于 .NET 運行時的垃圾回收器,跟蹤這些指針是一項成本相對高昂的操作。因此,運行時將這些引用約束為僅存在于堆棧上,因為它隱式規(guī)定了可以存在的內(nèi)部指針數(shù)量下限。
- 對 Span 執(zhí)行的讀取和寫入操作不是原子操作。如果多個線程同時對 Span 在堆上的字段執(zhí)行讀取和寫入操作,存在"撕裂"風險。
這個限制決定了無法將 Span 裝箱,進而無法將 Span<T> 與現(xiàn)有反射調(diào)用 API結(jié)合使用,也無法作為泛型參數(shù)。
對于大部分同步處理功能,這個并沒有太大的影響,但由于span<T>無法存儲到堆,從而導致其無法在異步上下文中使用。為了解決這個問題,.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 新增的重要組成部分
原文鏈接:https://www.cnblogs.com/TianFang/p/9193360.html
相關推薦
- 2022-07-18 Qt和Windows消息通信機制
- 2022-05-21 一次線上mongo慢查詢問題排查處理記錄_MongoDB
- 2022-08-16 python+pytest接口自動化參數(shù)關聯(lián)_python
- 2022-10-10 AOSP源碼下載示例代碼_Android
- 2022-08-04 如何利用python實現(xiàn)列表嵌套字典取值_python
- 2022-06-29 python人工智能tensorflow函數(shù)tf.layers.dense使用方法_python
- 2022-07-13 Docker技術_Docker與傳統(tǒng)虛擬機以及傳統(tǒng)容器的差異
- 2022-09-03 golang?四則運算計算器yacc歸約手寫實現(xiàn)_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支