当前位置: 代码网 > it编程>编程语言>Asp.net > .net中的Span<T>类和Memory<T>类介绍

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

2024年05月15日 Asp.net 我要评论
.net core 2.1的重头戏就是性能,其中最重要的两个类就是span和memory,本文这里简单的介绍一下这两个类的使用。什么是 span<t>span<t> 是新一种新

.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>类的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com