.net中的Span<T>类和Memory<T>类介绍

 更新时间:2022年07月01日 11:11:56   作者:天方  
这篇文章介绍了.net中的Span<T>类和Memory<T>类,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

.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的强大的功能。

参考文章:

C# - Span 全面介绍:探索 .NET 新增的重要组成部分

到此这篇关于.net中Span<T>类和Memory<T>类的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持程序员之家。

相关文章

  • ASP.NET中BulletedList列表控件使用及详解

    ASP.NET中BulletedList列表控件使用及详解

    本文主要介绍了ASP.NET中BulletedList列表控件的详细使用方法,讲解各属性的含义以及三种显示模式,希望能帮到大家。
    2016-04-04
  • ASP.Net?Core?MVC基础系列之环境设置

    ASP.Net?Core?MVC基础系列之环境设置

    这篇文章介绍了ASP.Net?Core?MVC环境设置的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • 答你所问 .NET小常识 方便学习asp.net的朋友

    答你所问 .NET小常识 方便学习asp.net的朋友

    这篇文章主要介绍了.NET小常识,对于想学习.net的朋友有个参考,一些问答与基础介绍,对于刚开始接触.net的朋友很有帮助,下面大家一起了解下吧
    2012-05-05
  • asp.net 专业源代码打包工具

    asp.net 专业源代码打包工具

    我想很多人都在网上下载过一些示例代码,或者收到一些别人给的示例代码。通常为了方便,都是打成一个压缩包的形式
    2012-03-03
  • .Net结构型设计模式之装饰模式(Decorator)

    .Net结构型设计模式之装饰模式(Decorator)

    这篇文章介绍了.Net结构型设计模式之装饰模式(Decorator),文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • ASP.NET?Core?MVC路由(Routing)的用法

    ASP.NET?Core?MVC路由(Routing)的用法

    这篇文章介绍了ASP.NET?Core?MVC路由(Routing)的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • WPF框架Prism中模块Module用法

    WPF框架Prism中模块Module用法

    这篇文章介绍了WPF框架Prism中模块Module的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • ASP.NET MVC使用区域(Area)功能

    ASP.NET MVC使用区域(Area)功能

    这篇文章介绍了ASP.NET MVC使用区域(Area)功能的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • .Net行为型设计模式之状态模式(State)

    .Net行为型设计模式之状态模式(State)

    这篇文章介绍了.Net行为型设计模式之状态模式(State),文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • C#声明方法实例说明

    C#声明方法实例说明

    方法(Method)是一个已命名的语句集。如果以前使用过其他编程语言,如C或Visual Basic等,就可以将方法视为函数或者子程序相似的东西。每个方法都有一个名称和一个主体。方法名应该是一个有意义的标识符,它应描述出方法的用途(如CalculateIncomeTax)。方法主体包含了调用方法时实际执行的语句。你可以为大多数方法提供一些数据来进行处理,并让它返回一些信息(通常是处理结果)。方法是一种基本的、功能强大的编程机制。
    2008-04-04

最新评论

?


http://www.vxiaotou.com