自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C# 語法糖之聊聊 Span 的底層玩法

開發(fā) 前端
當(dāng)年的 C# 一個亮點(diǎn)就是屏蔽了指針,自動內(nèi)存托管,可以讓程序員更加專注于業(yè)務(wù),現(xiàn)如今策略變了,C# 要變得更加高性能,既然要做高性能那必然少不了指針,而指針又是面向 托管層 編程的程序員最怕的東西,所以就盡可能的封裝,弄一套屬于自己的托管指針玩法。

把 Span 歸于語法糖,可能有些偏了,但偏了就偏了,哈哈,只要是分享就好,C# 發(fā)展至今,已經(jīng)是一門非常重的語言了,所有想要的它都要,即可以:

  1. 面向過程編程
  2. 面向?qū)ο缶幊?/li>
  3. 面向函數(shù)式編程
  4. 面向異步編程
  5. 面向泛型編程

既能做到 高開發(fā)效率 ,又能做到 高性能編程。

這里的 Span 就歸結(jié)于 高性能編程 這個范疇了。

一:Span 是什么

當(dāng)年的 C# 一個亮點(diǎn)就是屏蔽了指針,自動內(nèi)存托管,可以讓程序員更加專注于業(yè)務(wù),現(xiàn)如今策略變了,C# 要變得更加高性能,既然要做高性能那必然少不了指針,而指針又是面向 托管層 編程的程序員最怕的東西,所以就盡可能的封裝,弄一套屬于自己的托管指針玩法。

Span 即屬于托管指針玩法 的一個典型代表,如果你用 ILSpy 去看它的 struct 結(jié)構(gòu),本質(zhì)上就兩個成員,一個叫 _pointer,一個叫 _length,參考如下代碼:

public readonly ref struct Span<T>
    {
        internal readonly ByReference<T> _pointer;

        private readonly int _length;
    }

pointer 是 指定起點(diǎn), length 是 控制邊界,如果用 C 來模擬,大概就是這個樣子。

struct Span {
    void* ptr;
 int length;
};

畫個圖大概就是這樣子。

圖片圖片

二:Span 的場景在哪里

有了指針,就可以對 內(nèi)存 進(jìn)行原地操作,只要能 原地操作 ,那就可以破掉 語言層面 上的諸多限制,實(shí)現(xiàn)接近 C/C++ 級的高性能,有些朋友可能要問了,語言層面有什么限制?比如最典型的 string ,大家都知道 string 是一個 writeoncopy 特性的字符串,只要你動它一下,它就會繁殖,接下來我們就拿 string 舉個例子。

1. string 中的數(shù)字求 sum

在很久以前你可能會這么做。

static void Main(string[] args)
        {
            var s = "97 3";

            var arr = s.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);

            var sum = Convert.ToInt32(arr[0]) + Convert.ToInt32(arr[1]);

            Console.WriteLine(sum);
        }

圖片圖片

從代碼可以看出,對 string 進(jìn)行 Split 會導(dǎo)致生成多個小 string 對象,那有沒有辦法不用生成小string呢?這就需要用到托管版的 Span 做原地處理了。

static void Main(string[] args)
        {
            var s = "97 3";

            var position = s.IndexOf(' ');

            ReadOnlySpan<char> span = s.AsSpan();

            var num1 = int.Parse(span.Slice(0, position));

            var num2 = int.Parse(span.Slice(position));

            Console.WriteLine(num1 + num2);
        }

圖片圖片

Span 的這種做法就是通過 _pointer 指針在內(nèi)存地址上進(jìn)行移動來完成,如果看不明白,我可以用 C 來模擬一下。

#include <iostream>

struct Span {
 int length;
 void* ptr;
};

void sum(Span* span);

int main()
{
 Span span;
 span.ptr = (char*)"97 3";
 span.length = strlen((char*)span.ptr);

 sum(&span);
}

void sum(Span* span) {

 int sum = 0;

 char* position = strchr((char*)span->ptr, ' ');

 Span span1;
 span1.ptr = span->ptr;
 span1.length = (position - span->ptr) / sizeof(char);

 Span span2;
 span2.ptr = position;
 span2.length = span->length - span1.length - 1;

 int num1= atoi((char*)span1.ptr);
 int num2= atoi((char*)span2.ptr);

 sum = num1 + num2;

 printf("sum=%d", sum);
}

圖片圖片

雖然代碼有點(diǎn)多,但邏輯還是很清楚的。

如果大家明白 Span 所封裝的底層指針玩法,我想這其實(shí)沒什么難的,本篇就說到這里吧,希望對你有幫助。

責(zé)任編輯:武曉燕 來源: 一線碼農(nóng)聊技術(shù)
相關(guān)推薦

2023-09-11 08:20:17

對象閉包底層

2025-01-10 08:15:22

C#異步底層

2022-05-30 16:19:26

C#多態(tài)底層虛方法

2016-06-02 15:10:12

SwiftSelector

2009-08-19 15:38:59

C#代碼

2020-12-08 07:51:53

Java語法糖泛型

2022-02-14 08:04:02

Go語法糖編譯器

2009-08-27 11:43:31

C#語法

2025-04-08 00:07:37

語法糖C#代碼

2021-01-30 11:12:21

C#List數(shù)據(jù)

2024-05-15 09:11:51

委托事件C#

2024-10-21 16:59:37

C#編程多線程

2009-08-18 12:52:33

C#枚舉類型

2016-10-14 14:04:34

JAVA語法main

2009-08-20 13:23:00

C#正則表達(dá)式

2024-09-11 16:34:38

語法糖Java語言

2023-10-09 07:11:03

排序算法序列

2024-06-26 12:59:29

C#代碼開發(fā)

2024-09-29 09:28:38

Action?C#

2021-03-15 08:18:23

C#反射模塊
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號