【5min+】传说中的孪生兄弟? Memory and Span
系列介绍
【五分钟的dotnet】是一个利用您的碎片化时间来学习和丰富.net知识的博文系列。它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net知识等等。
5min+不是超过5分钟的意思,"+"是知识的增加。so,它是让您花费5分钟以下的时间来提升您的知识储备量。
正文
在上一篇文章:《闪电光速拳? .NetCore 中的Span》 中我们提到了在.net core 2.x 所新增的一个类型:Span。
它与咱们传统使用的基础类型相比具有超高的性能,原因是它减少了大量的内存分配和数据量复制,并且它所分配的数据内存是连续的。
但是您会发现它无法用在我们项目的某些地方,它独特的 ref结构 使它没有办法跨线程使用、更没有办法使用Lambda表达式。

特别是在AspNetCore中,咱们会使用到大量的异步操作方法。“所以,这个时候如果我们又想跨线程操作数据又想获得类似Span这样的性能怎么办呢?” 上一篇文章我们留下了这样的一个问题,所以现在就是到了还愿的时候了。它就是与Span一起发布的孪生兄弟: Memory。

狮子座和射手座黄金圣斗士同样具备超越光速的能力
什么是Memory
那什么是Memory呢?不妨我们先来猜测一下,它的结构是什么样子。毕竟它是Span的孪生兄弟,而Span的结构我们在前面就了解过了:
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();
//.....
}
当时我们说Span有各种缺陷的原因是由于它独特的 ref struct 关键字所导致的,导致它无法拆箱装箱、无法书写Lambda、无法跨线程等。但是它兄弟却可以克服缺点,所以我们想想它会和Span在声明上有哪些差距呢? 是的,您可能已经想到了:它不会有 ref 关键字了。
所以,我们看到它的内部结构就是酱紫的:
public readonly struct Memory<T>
{
public static Memory<T> Empty { get; }
public bool IsEmpty { get; }
public int Length { get; }
public Span<T> Span { get; }
public void CopyTo([NullableAttribute(new[] { 0, 1 })] Memory<T> destination);
public MemoryHandle Pin();
public Memory<T> Slice(int start, int length);
public T[] ToArray();
public override string ToString();
}
和我们猜想的一样。它少了ref关键字,内部方法也和Span差不多(同样拥有CopyTo,Slice等),但是还是有一些差异,比如多了Pin方法,Span属性等。
被声明为ref struct的结构,叫做“ByRefLike”。所以在我们在进行反射的时候,我们使用Type会看到有这样一个属性:IsByRefLike。

好像有点超纲了哈(>人<;)
按照MSDN给出的解释:
该结构是使用中的C# ref struct 关键字声明的。 不能将类似 byref 的结构的实例放置在托管堆上。
所以这也是为什么上一篇文章说的:Span只能放置在内存栈中的原因。
那么反过来想,没有了ref关键字之后。Memory是不是就可以放置在托管堆上了呢?是不是就可以进行拆装箱,克隆副本供其它线程的内存栈使用了呢? 好吧,可能是这样。所以这也许就是它能够被允许跨线程使用的原因吧。
进行到了这一步,那我们再回过头来想想Memory是什么呢? 其实现在我们心里其实都已经有个底了:
与 Span<T>一样,Memory<T> 表示内存的连续区域。 但 Span<T>不同,Memory<T> 不是ref 结构。 这意味着 Memory<T> 可以放置在托管堆上,而 Span<T> 不能。 因此,Memory<T> 结构与 Span<T> 实例没有相同的限制。 具体而言:
- 它可用作类中的字段。
- 它可跨 await 和 yield 边界使用。
除了 Memory<T>之外,还可以使用 System.ReadOnlyMemory<T> 来表示不可变或只读内存。
这是MSDN给出来的解释,不是我乱编的哈
【5min+】传说中的孪生兄弟? Memory and Span的更多相关文章
- 阿里云产品介绍(二):云服务器ECS的孪生兄弟们
上一篇介绍的云服务器ECS,是阿里云最基础的产品,也是每一个云计算厂商最基础的产品,俗称爆款.除了标准的云服务器,阿里云也不停的在推出面向特殊业务场地的云服务器,可以说是ECS的孪生兄弟们. 这一篇就 ...
- Android图表库MPAndroidChart(十)——散点图的孪生兄弟气泡图
Android图表库MPAndroidChart(十)--散点图的孪生兄弟气泡图 起泡图和散点图如出一辙,但是个人认为要比散点图好看一点,我们来看下实际的演示效果 这个和散点图的实现很相似,我们一起来 ...
- [译]C# 7系列,Part 10: Span<T> and universal memory management Span<T>和统一内存管理
原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/25/c-7-series-part-10-spant-and-universal-memory- ...
- 内存包装类 Memory 和 Span 相关类型
1. 前言 2. 简介 3. Memory<T>和Span<T>使用准则 3.1. 所有者, 消费者和生命周期管理 3.2. Memory<T> 和所有者/消费者模 ...
- 深入理解计算机系统(4.1)---X86的孪生兄弟,Y86指令体系结构
引言 各位猿友们好,计算机系统系列很久没更新了,实在是抱歉之极.新的一年,为了给计算机系统系列添加一些新的元素,LZ将其更改为书的原名<深入理解计算机系统>.这本书非常厚,而且难度较高,L ...
- grep与孪生兄弟egrep差异
egrep是对grep的功能扩展,让其支持正则更加完美! #grep与egrep不同 egrep完全支持正则 ls |grep -i '[a-z]\{3\}' === ls |egrep -i ...
- SpringMVC的孪生兄弟WebFlux
一.入门文字介绍 官方口水话简短翻译: Spring WebFlux是一个非阻塞的Web框架,用于利用多核,短时间可一处理大量并发连接. 非阻塞式 在servlet3.1提供了非阻塞的API,WebF ...
- .net下的span和memory
.net core 2.1的重头戏就是性能,其中最重要的两个类就是span和memory,本文这里简单的介绍一下这两个类的使用. 什么是 Span<T> Span<T> 是新一 ...
- 【C# IO 操作 】内存包装类 Memory <T>和 Span<T> 相关类型
简介 .NET 包含多个相互关联的类型,它们表示任意内存的连续的强类型区域. 这些方法包括: System.Span<T> 用于访问连续的内存区域 得到该类型的实例: 1个T类型的数组 1 ...
随机推荐
- P1076 单词覆盖还原
题目描述 一个长度为 \(l(3\le l\le 255)\) 的字符串中被反复贴有 boy 和 girl 两单词,后贴上的可能覆盖已贴上的单词(没有被覆盖的用句点表示),最终每个单词至少有一个字符没 ...
- 通过作用域链解析js函数一些难以理解的的作用域问题
基本原理 js函数在执行时,系统会创建一个隐式的属性scope,scope中存储的是函数的作用域链. 通过对这个scope的分析,就能解释JavaScript中许多难以理解的问题: 例1: funct ...
- 性能测试基础-开门篇3(LR常用函数介绍)
LR常用的函数,协议不一样函数会不一样,这里简单的介绍下HTTP\WEBSERVICE\SOCKET协议常用函数: HTTP: web_set_max_html_param_len("102 ...
- C# AutoResetEvent 理解
.. AutoResetEvent在内存中保持着一个bool值值为False,则使线程阻塞:值为True,使线程退出阻塞: 创建AutoResetEvent对象的实例,在函数构造中传递默认的bool值 ...
- codeforces 540E 离散化技巧+线段树/树状数组求逆序对
传送门:https://codeforces.com/contest/540/problem/E 题意: 有一段无限长的序列,有n次交换,每次将u位置的元素和v位置的元素交换,问n次交换后这个序列的逆 ...
- Keras mlp 手写数字识别示例
#基于mnist数据集的手写数字识别 #构造了三层全连接层组成的多层感知机,最后一层为输出层 #基于Keras 2.1.1 Tensorflow 1.4.0 代码: import keras from ...
- HDU4528 小明捉迷藏 [搜索-BFS]
一.题意 小明S在迷宫n*m中找大明D和二明E,障碍物X不能走,问你计算是否能在时间t内找到大明和二明 二.分析 2.1与普通的BFS不同,这里可以走回头路,这里应该建立四维的标记数组标记数组,例如v ...
- 一些实战中总结的 javascript 开发经验
Javascript 的很多扩展的特性是的它变得更加的犀利, 同时也给予程序员机会创建更漂亮并且更让用户喜欢的网站. 尽管很多的开发人员都乐于颂扬 javascript,但是仍旧有人看到它的阴暗面. ...
- 调用微软未公开ZwQueryInformationThread函数根据线程句柄获取线程ID
这段时间公司项目中为了支持XP系统同事代码中用到了 GetThreadId 这个微软的API 但是这个API最低支持版本是 Windows version Windows Vista [desktop ...
- 【题解】BZOJ4548 小奇的糖果(树状数组)
[题解]BZOJ4548 小奇的糖果(树状数组) 说在前面:我有个同学叫小奇,他有一个朋友叫达达,达达特爱地理和旅游,初中经常AK地理,好怀恋和他已经达达一起到当时初中附近许多楼盘的顶楼逛的时光... ...