Span 提供任意記憶體的連續區域的型別安全和記憶體安全表示形式。它是在堆疊而不是託管堆上分配的ref結構,是對任意記憶體塊的抽象 。
1.關於Span
-
在NET Core 2.1中首次引入
-
提供對任意記憶體上的連續區域的讀寫檢視
- 利用索引/迭代來修改範圍內的記憶體
- 幾乎無開銷
2.和記憶體的關係
Span 表示任意記憶體的連續區域。 Span<T>例項通常用於儲存陣列的元素或陣列的一部分。 但是,與陣列不同, Span<T>例項可以指向堆疊上託管的記憶體、本機記憶體或託管的記憶體。
3.效能測試
Span通常用來處理陣列,所以本次測試的場景是陣列的切分:從一個陣列的中間元素開始,獲取並返回四分之一個元素。
3.1 陣列初始化
這裡我們準備一個陣列分三種不同長度進行初始化,有利於覆蓋到更多的測試情況。
3.2 測試採用三種方式,用BenchmarkDotNet比較一下:
第一種(常規):
第二種(複製):
第三種(Span切片):
效能測試結果如下,可以看到Span的速度是很快的,且不佔記憶體。
4. 切片
Span<T>.Slice()方法就是對記憶體進行切片,第三種方法區別於前兩種,本質上不建立和銷燬物件,可以認為是做到了記憶體0分配
5. ReadOnlySpan
ReadOnlySpan是Span的只讀表示形式,通常用在string的切片(因為string的不可變性)
6. Span<T>侷限性
-
Span是僅限存活在堆疊上的值型別
-
Span不能是非堆疊型別的欄位
-
Span不能被裝箱
-
Span不能是非同步方法的引數或區域性變數
-
Span不能被lambda表示式捕獲