.net下的span和memory
.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和memory的更多相关文章
- System.Span, System.Memory,还有System.IO.Pipelines
System.Span, System.Memory,还有System.IO.Pipelines 使用高性能Pipelines构建.NET通讯程序 .NET Standard支持一组新的API,Sys ...
- linux 下tomcat出现 Native memory allocation (malloc) failed to allocate 1915224064 bytes for committing reserved memory问题
## There is insufficient memory for the Java Runtime Environment to continue.# Native memory allocat ...
- C++库研究笔记——Linux下是否需要使用memory pool?
Linux Slab分配器(一)--概述 Linux slab 分配器剖析 C++库研究笔记——内存池实现 做了一些测试:发现linux使用内存池与否没有明显差别,仅仅有2倍. Linux内存处理机制 ...
- Js/如何操作div下面的span元素或者是img之类的标签元素
$("div[name='MatTypeName']").click(function (e) { $("div[name='MatTypeName']").e ...
- vue中用v-for循环出出来的div下面的span不给宽度也能相对于div居中
效果图 1.html <div> <div v-on:mousemove="dataDetails($event, item)" v-on:mouseleave= ...
- 《ASP.NET Core 高性能系列》Span<T>和Memory<T>
一.Span<T>概述 原文:Provides a type- and memory-safe representation of a contiguous region of arbit ...
- 内存包装类 Memory 和 Span 相关类型
1. 前言 2. 简介 3. Memory<T>和Span<T>使用准则 3.1. 所有者, 消费者和生命周期管理 3.2. Memory<T> 和所有者/消费者模 ...
- 在 C# 中使用 Span<T> 和 Memory<T> 编写高性能代码
目录 在 C# 中使用 Span 和 Memory 编写高性能代码 .NET 中支持的内存类型 .NET Core 2.1 中新增的类型 访问连续内存: Span 和 Memory Span 介绍 C ...
- Label下FormattedText中的Span无法使用Binding的解决方法
在Xamarin.Forms中,Xaml的模板功能并没有原生WPF丰富,比如Label中虽然有FormattedText可以添加Span来丰富Label的功能,但是下面的Span中的Text并没有绑定 ...
随机推荐
- Vue.js绑定内联样式
1.对象语法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...
- 自己动手开发Socks5代理服务器
一.Socks5协议简介 socks5是基于传输层的协议,客户端和服务器经过两次握手协商之后服务端为客户端建立一条到目标服务器的通道,在传输层转发TCP/UDP流量. 关于socks5协议规范,到处都 ...
- Ettercap之ARP+DNS欺骗
1.网络攻击拓扑环境 网关:192.168.133.2 攻击者:192.168.133.128 受害者:192.168.133.137 2.原理讲解 ARP欺骗 简介:ARP(Address Reso ...
- Nagios介绍
Nagios介绍 Nagios是一款功能强大.优秀的开源监控系统,它能够让你发现和解决IT架构中存在的问题,避免这些问题影响到关键业务流程. Nagios最早于1999年发布,它在开源社区的影响力是相 ...
- ps和top的区别,以及各参数意思
这两个命令都是查看系统进程信息的命令,但是用处有点儿不同 1.ps命令--提供系统过去信息的一次性快照 也就是说ps命令能够查看刚刚系统的进程信息 命令:ps aux或者ps lax [root@L ...
- H5新增语义化标签
一.根据页面的结构,由div派生的标签. <header> <footer> <nav> 导航 在H4中导航栏一般用ul-li标签,H5中可以直接用<nav& ...
- Android Service总结06 之AIDL
Android Service总结06 之AIDL 版本 版本说明 发布时间 发布人 V1.0 初始版本 2013-04-03 Skywang 1 AIDL介绍 AIDL,即And ...
- AC自动机算法学习
KMP+TRIE int val[1000100][31],tot; int tr[1000100]; int fail[1000100]; struct AC_Trie{ void clean(){ ...
- MVC母板页传递数据
问题:判断Session 失败 结果: if (Session[SessionKey.AccountInfo] != null) { ViewData["AdminUser"] = ...
- appium入门级教程(3)—— 安装 Android SDK
前言 搭建Android平台不是必须的,如果你不想使用 Android 模拟器运行测试的话可以跳过,不过,建议安装:原生 Android 好折腾!关键是它自带的一些工具是做 appium 测试必须要用 ...