.net下的span和memory

2021-03-02 DotNet開發跳槽

.net core 2.1的重頭戲就是性能,其中最重要的兩個類就是span和memory,本文這裡簡單的介紹一下這兩個類的使用。

什麼是 Span<T>

Span<T> 是新一種新值類型。它表示一段連續的區域,它通常和數組關聯,表示數組中的一部分內存。

var        arr   = new byte[10];
Span<byte> bytes = arr;

也可以取數組中的一部分:

var bytes = new Span<byte>(arr, 3, 5);

初一乍看,span<T>和ArraySegment<T>非常類似,但span更加強大得多,它不但能用於分離數組,還可以引用棧上的數據。

Span<byte> bytes = stackalloc byte[2];

也可以引用指針數據,

Span<byte> bytes;
unsafe { bytes = new Span<byte>((byte*)ptr, 1); }

另外,span還支持 reinterpret_cast 的理念,即可以將 Span<byte> 強制轉換為 Span<int>,配合MemoryMarshal類使用,span<T>大多數的時候都可以代替指針了。

除了功能更加強大外,span在bcl庫中也得到了更多的支持,大多數支持數組的函數現在基本上都能直接支持span了,如:

var inputSpan = input.AsSpan();
int first     = int.Parse(inputSpan.Slice(3, 5));

這個函數中,int.Parse函數就能直接支持span,並且由於不產生子字符串,比使用substring的方法性能更高。

另外,系統也支持數組類型到span的隱式轉換,同時提供了AsSpan的顯示擴展方法,方便將數組類型轉換為span。

除了功能強大外,span的性能也是非常高的,對span的操作基本上和訪問數組一樣高,無需通過計算來確定指針開頭及其起始偏移,因為"引用"欄位本身已對兩者進行了封裝。相比之下,ArraySegment<T> 有單獨的偏移欄位,這就增加了索引編制和數據傳遞操作的成本。

什麼是 Memory<T>

Span<T>雖然強大而好用,但它只能存在於棧上,而不能存在於堆上,原因主要有如下兩點:

span包含"引用"欄位(如數組的開頭),這些引用被稱為"內部指針"。對於 .NET 運行時的垃圾回收器,跟蹤這些指針是一項成本相對高昂的操作。因此,運行時將這些引用約束為僅存在於堆棧上,因為它隱式規定了可以存在的內部指針數量下限。

對 Span 執行的讀取和寫入操作不是原子操作。如果多個線程同時對 Span 在堆上的欄位執行讀取和寫入操作,存在"撕裂"風險。

這個限制決定了無法將 Span 裝箱,進而無法將 Span<T> 與現有反射調用 API結合使用,也無法作為泛型參數。

對於大部分同步處理功能,這個並沒有太大的影響,但由於span<T>無法存儲到堆,從而導致其無法在異步上下文中使用。為了解決這個問題,.net引入了一個新類型Memory<T>。

Memory和span的使用方法大同小異,

var arr   = new byte[10];
var bytes = new Memory<byte>(arr, 3, 5);

不同之處在於 Memory<T> 是不類似引用的結構,可以存在於堆上。.net bcl庫對memory也做了很好的支持,如Stream.ReadAsync就能直接支持memory<byte>作為參數。

另外,也可以從Memory的Span屬性創建指向該Memory的span,這樣也可以使用span的強大的功能。

出處:https://www.cnblogs.com/TianFang/p/9193360.html

版權申明:本文來源於網友收集或網友提供,如果有侵權,請轉告版主或者留言,本公眾號立即刪除。

相關焦點

  • .NET內存包裝類 Memory 和 Span 相關類型
    Memory<T>和Span<T>使用準則1. 前言此文章是官方文檔的翻譯,由於官方文檔中文版是機器翻譯的,有些部分有疏漏和錯誤,所以本人進行了翻譯供大家學習,如有問題歡迎指正。
  • div和span
    這時我們就需要一個屬性span span只是一個容器,並不實際顯示
  • CAC· Reading | nettime: Net.Art - the origin
    Vuk was very much amased and exited: the net itself gave him a name for activity he was involved in! He immediately started to use this term.
  • 網頁設計中的Span和Div的區別
    首頁 > 教程 > 關鍵詞 > div最新資訊 > 正文 網頁設計中的Span和Div的區別
  • div&&span標籤
    div和span元素沒有特定的語義,都是用來幫助頁面排版的塊元素。div&&span標籤div:塊級元素,可定義文檔中的分區或分節,用來為HTML文檔內大塊的內容提供結構和背景。通過在頁面中放置多個div並定義好位置及大小等屬性,可以達到給網頁布局的效果。
  • div && span 標籤
    div:塊級元素,可定義文檔中的分區或分節,用來為HTML文檔內大塊的內容提供結構和背景。通過在頁面中放置多個div並定義好位置及大小等屬性,可以達到給網頁布局的效果。特點:獨佔一行。span:行內元素,主要使用場合是與css一同使用,為部分文本設置樣式屬性。特點:可一行多個同時顯示。
  • css教程:網頁中Span和Div的區別
    HTML只是賦予內容的手段,大部分HTML標籤都有其意義(標籤p創建段落,h1標籤創建標題等等)的,然而span和div標籤似乎沒有任何內容上的意義,聽起來就像一個泡沫做成的錘子一樣無用。
  • HTML的SPAN和DIV的區別
    SPAN 和 DIV 的區別在於,DIV(division)是一個塊級元素,可以包含段落、標題、表格,乃至諸如章節、摘要和備註等。而SPAN 是行內元素,SPAN 的前後是不會換行的,它沒有結構的意義,純粹是應用樣式,當其他行內元素都不合適時,可以使用SPAN。
  • 標準布局中DIV元素和SPAN元素的區別和應用
    兩者最明顯的區別是:DIV(division)是一個塊級元素,可以包含段 落、標題、表格,乃至諸如章節、摘要和備註等。而SPAN 是行內元素,SPAN 的前後是不會換行的,它沒有結構的意義,純粹是應用樣式,當其他行內元素都不合適時,可以使用SPAN。 塊元素相當於內嵌元素在前後各加一個<br>換行。
  • 使用SQL Server In-Memory存儲ASP.NET的會話狀態
    這裡有許多提供商可供選擇,包括Microsoft和第三方開發者提供的工具。Yes Excellent *需要在 in-memory
  • HTML中div和span有3大區別,你了解幾個!
    HTML中的span標記和div標記在使用css排版網頁時,span和div常用的兩個的標記。利用這個兩個標記,加上css樣式控制,可以實現很複雜的網頁效果,下面為大家詳細講解一下他們區別和使用。span和div概念區別和相似點div標記是html3.0時提出來的,但是不常用,直到css的出現才慢慢變得應用廣泛起來。HTML4.0以後span才被引入,主要針對樣式表設計的。
  • 網頁HTML教程:介紹span和div標籤的使用
    首頁 > 教程 > 關鍵詞 > 最新資訊 > 正文 網頁HTML教程:介紹span和div標籤的使用
  • html中span標籤的詳細介紹
    本篇將介紹html中span標籤的詳細用法,有興趣的朋友可以了解一下!「span」作為英文單詞有「範圍」的意思,那它作為html中的標籤又充當什麼樣的角色呢?接下來我們一起來看看html中span標籤的定義及用法吧!
  • NET開發-在ASP.NET WebForm應用程式中使用C#操作Label控制項的屬性
    概述Label控制項是標籤控制項,是ASP.NET伺服器端控制項,用於顯示文本值,對應於HTML中的span標記。在ASP.NET WebForm框架中,Label控制項是微軟對HTML的span標記進行了封裝,使可以在後臺代碼中,使用C#代碼給span標記賦值。在Visual Studio中,可以在「工具欄」中直接拖拽Label控制項到Web窗體上。
  • .NET Standard 2.1 發布,進一步使 .NET 實現一致
    使用 span 的基礎 API。雖然 Span 已經可以作為 .NET Standard 兼容的 NuGet 包(System.Memor)使用,但添加此包不能擴展 .NET Standard 類型的成員去使用 span。.NET Core 2.1 添加了許多允許使用 span 的API,如  Stream.Read(Span) 。
  • 理解memory barrier
    memory ordered又和speculative execution(預測執行)有極大關係。硬體層面來說,所有的CPU都會有準確的memory model描述,說明了在哪裡情況下會出現哪些亂序執行。我們先不考慮具體的軟體或具體的硬體情況,僅僅從邏輯上考慮這個問題。最簡單的模型就是只簡化內存操作為Store(內存存儲)和Load(內存讀取)這兩個操作,因此2×2可以組合出至少以下4種序列。
  • DenseNet——CNN經典網絡模型詳解(pytorch實現)
    Hl包括BN,ReLU和3*3的卷積。 所以從這兩個公式就能看出DenseNet和ResNet在本質上的區別,太精闢了。接著說下論文中一直提到的Identity function: 很簡單 就是輸出等於輸入傳統的前饋網絡結構可以看成處理網絡狀態(特徵圖?)的算法,狀態從層之間傳遞,每個層從之前層讀入狀態,然後寫入之後層,可能會改變狀態,也會保持傳遞不變的信息。
  • C++ atomic memory model和Arm實現方式
    C++  atomic memory model  和 Arm構架實現C++的memory model
  • 我的世界out of memory怎麼辦 out of memory解決辦法
    ,不知道怎麼回事,當我們遇到我的世界out of memory怎麼辦呢?   從錯誤消息顯示的原因是:java虛擬機(JVM)內存空間不足造成。out of memory在java開發中還是偶爾會遇到,下面我來給你說明下具體原因:   內存是運行電腦時非常關鍵的載體,你的每一步操作都會臨時存儲在內存中,內存有固定大小比如2G,那麼開機時可能你的內存只佔了500M,隨後你打開遊戲,遊戲就會把數據臨時寫到內存中,這時慢慢的內存佔用可能就升到1G了,這是內存升高的原因。