【5min+】閃電光速拳? .NetCore 中的Span

来源:https://www.cnblogs.com/uoyo/archive/2020/01/17/12207148.html
-Advertisement-
Play Games

系列介紹 簡介 【五分鐘的DotNet】是一個利用您的碎片化時間來學習和豐富.net知識的博文系列。它所包含了.net體系中可能會涉及到的方方面面,比如C 的小細節,AspnetCore,微服務中的.net知識等等。 5min+不是超過5分鐘的意思,"+"是知識的增加。so,它是讓您花費5分鐘以下的 ...


系列介紹

簡介

【五分鐘的DotNet】是一個利用您的碎片化時間來學習和豐富.net知識的博文系列。它所包含了.net體系中可能會涉及到的方方面面,比如C#的小細節,AspnetCore,微服務中的.net知識等等。
5min+不是超過5分鐘的意思,"+"是知識的增加。so,它是讓您花費5分鐘以下的時間來提升您的知識儲備量。

正文

在dotnet core2.x之後,引入了一個叫做Span<T>的類型。如果您的項目已經升級到了新版的dotnet core 以及使用C# 7+。您會發現我們曾經使用的許許多多類型都增加了一個擴展方法“AsSpan()”。在Vs中小手一點就會出現:


var s = ("xxx").AsSpan();
var s1 = new byte[10].AsSpan();
//.......more

那麼這個家伙到底是個什麼東西?怎麼用呢?

先來扒一扒它的內部方法:

public readonly ref struct Span<T>
{
    public void Clear();
    public void CopyTo([NullableAttribute(new[] { 0, 1 })] Span<T> destination);
    public void Fill(T value);
    public Enumerator GetEnumerator();
    public Span<T> Slice(int start, int length);
    public T[] ToArray();
    public override string ToString();

    //.....
}

這裡只展示它部分的方法,但是關鍵的一點我們可以看到:它是一個結構性(struct 關鍵字)。

而且!!而且!!! 你沒看錯,它還加了一個ref關鍵字。

所以按照我們在上一篇文章中介紹過的 .net中的棧和堆,我們猜想這種結構類型的數據應該是存放在記憶體棧中,具有很快的訪問速度。而且它擁有了ref關鍵字,證明它具有ref結構體的特點:

  • 不能對 ref struct 裝箱
  • ref struct 類型不能實現介面
  • 不能將 ref struct 聲明為類或常規結構的欄位成員
  • 不能聲明非同步方法中屬於 ref struct 類型的本地變數
  • 無法在迭代器中聲明 ref struct 本地變數
  • 無法捕獲 Lambda 表達式或本地函數中的 ref struct 變數

而且根據它公開的這些方法,我們會發現它有點類似我們常用的幾個基礎類型:string 、 byte[] ……。

所以直覺告訴我們,它應該是一個拿來存放數據的類型。

so,來看看MSDN - Magazine中它的解釋:

System.Span<T> 是在 .NET 中發揮關鍵作用的新值類型。使用它,可以表示任意記憶體的相鄰區域,無論相應記憶體是與托管對象相關聯,還是通過互操作由本機代碼提供,亦或是位於堆棧上。除了具有上述用途外,它仍能確保全全訪問和高性能特性,就像數組一樣。

果不其然,和我們猜想的一樣。那麼它出現的意義是什麼呢? 性能!!!!

而且是超級快的性能。大家都知道以往如果我們想提高數據間的操作效率(比如數據偏移、裁剪等),就只能使用指針來操作記憶體中的數據。這樣雖然一波操作猛如虎,但是寫起來費勁不說,我們還得將傳統的C#代碼設置為不安全代碼,除了添加unsafe關鍵字之外還需要打開項目中執行不安全代碼的選項。

所以,有沒有辦法既不操作指針而又有高性能呢? 好吧,Span大爺來了。

Span在C# 7.x中被引入,所以它的年齡還算比較小,也是因為這些原因。以往的項目可能沒有辦法使用它。

它到底有多快

大家一般都是想直接看東西,所以我寫了一份對比的代碼。功能很簡單,都是截取字元串中的一部分代碼,並且進行多次的迴圈操作。

執行結果我都驚呆了:

x

是的,您沒有看錯。差距不是一般的大。

其實剛開始我以為Span並沒有什麼作用,因為我將數據源(圖中的compareStr)僅僅設置為了幾個單詞。然後對他們進行了1億的迴圈操作,但是最後的結果只有很小的差距,不到百分之30。

後來我想了一下,應該讓數據更貼近現實,於是就將一張圖片轉換為base64然後作為數據源。結果驚呆了,差了接近百倍。而且隨著迴圈次數和對數據源的操作次數的增多,Span和傳統字元串之間的性能差距更大。

傳說中的閃電光速拳到底有多快呢

x

它為什麼這麼快

它與傳統的string操作比起來為什麼會具有這麼快的速度呢? 按照我們之前的一些猜想和msdn所給出的一點信息,我們可以得到以下的結論:

  • 它分配堆棧上而不是在托管堆。
  • 它所創建的數據是記憶體連續的,因此具有更快的遍歷速度。

這些特點和string等原有類型比起來就非常的具有優勢了:原來對string操作涉及到大量的字元串分配和記憶體複製。所以當操作的數據量小的時候還好,但是隨著操作次數和處理數據量的增加之後,這是非常消耗性能的。

x

Span會給我們帶來什麼

那麼,既然它擁有如此高的性能,那麼我們該在什麼地方使用它呢?

這很簡單,如果您以前有對大量字元串進行截取或者處理的地方,一般都可以替換為Span。(為什麼是一般呢

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • import java.io.*; public class test13_6 { public static void main(String []args) throws Exception { FileOutputStream output=null; FileInputStream inpu ...
  • 原文:https://www.jianshu.com/p/e88d3f8151db JWT官網: https://jwt.io/ JWT(Java版)的github地址:https://github.com/jwtk/jjwt 什麼是JWT Json web token (JWT), 是為了在網路應 ...
  • 一、Unittest 單元測試框架,可用於自動化測試用力組織,執行,輸出結果 二、Unittest構成 1. Test Case 2. Test Suite 3. Test Fixture 4. Test Runner (圖片來源於網路) Test Case 一個測試用例是一個獨立的測試單元。它檢查 ...
  • 你可以訪問 "碼雲 樂優商城" 來獲取關於樂優商城的工程代碼。 你可以訪問 "百度雲 樂優優商城" 密碼:ppzy 來獲取關於樂優商城的資料。 一、介紹 樂優商城是一個全品類的電商購物網站(B2C),作為階段性學習工程。 二、軟體架構 三、前端技術選型 1. 基礎的HTML、CSS、JavaScri ...
  • 效果圖 首先是資料庫 /* Navicat MySQL Data Transfer Source Server : xm Source Server Version : 50553 Source Host : localhost:3306 Source Database : test Target ...
  • 一、概述 即時編譯器(Just In Time Compiler),也稱為 JIT 編譯器,它的主要工作是把熱點代碼編譯成與本地平臺相關的機器碼,併進行各種層次的優化,從而提高代碼執行的效率。 那麼什麼是熱點代碼呢?我們知道虛擬機通過解釋器(Interpreter)來執行位元組碼文件,當虛擬機發現某個 ...
  • 用已經搭建好 face_recognition,dlib 環境來進行人臉識別 未搭建好環境請參考:https://www.cnblogs.com/guihua-pingting/p/12201077.html 使用OpenCV 調用攝像頭 import face_recognition import ...
  • 微信公眾號: "Dotnet9" ,網站: "Dotnet9" ,問題或建議: "請網站留言" , 如果對您有所幫助: "歡迎贊賞" 。 C WPF可拖拽的TabControl 閱讀導航 1. 本文背景 2. 代碼實現 3. 本文參考 4. 源碼 1. 本文背景 本文介紹使用第三方開源庫 Draga ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...