系列介绍

【五分钟的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的更多相关文章

  1. 阿里云产品介绍(二):云服务器ECS的孪生兄弟们

    上一篇介绍的云服务器ECS,是阿里云最基础的产品,也是每一个云计算厂商最基础的产品,俗称爆款.除了标准的云服务器,阿里云也不停的在推出面向特殊业务场地的云服务器,可以说是ECS的孪生兄弟们. 这一篇就 ...

  2. Android图表库MPAndroidChart(十)——散点图的孪生兄弟气泡图

    Android图表库MPAndroidChart(十)--散点图的孪生兄弟气泡图 起泡图和散点图如出一辙,但是个人认为要比散点图好看一点,我们来看下实际的演示效果 这个和散点图的实现很相似,我们一起来 ...

  3. [译]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- ...

  4. 内存包装类 Memory 和 Span 相关类型

    1. 前言 2. 简介 3. Memory<T>和Span<T>使用准则 3.1. 所有者, 消费者和生命周期管理 3.2. Memory<T> 和所有者/消费者模 ...

  5. 深入理解计算机系统(4.1)---X86的孪生兄弟,Y86指令体系结构

    引言 各位猿友们好,计算机系统系列很久没更新了,实在是抱歉之极.新的一年,为了给计算机系统系列添加一些新的元素,LZ将其更改为书的原名<深入理解计算机系统>.这本书非常厚,而且难度较高,L ...

  6. grep与孪生兄弟egrep差异

    egrep是对grep的功能扩展,让其支持正则更加完美! #grep与egrep不同  egrep完全支持正则 ls |grep -i '[a-z]\{3\}'    === ls |egrep -i ...

  7. SpringMVC的孪生兄弟WebFlux

    一.入门文字介绍 官方口水话简短翻译: Spring WebFlux是一个非阻塞的Web框架,用于利用多核,短时间可一处理大量并发连接. 非阻塞式 在servlet3.1提供了非阻塞的API,WebF ...

  8. .net下的span和memory

    .net core 2.1的重头戏就是性能,其中最重要的两个类就是span和memory,本文这里简单的介绍一下这两个类的使用. 什么是 Span<T> Span<T> 是新一 ...

  9. 【C# IO 操作 】内存包装类 Memory <T>和 Span<T> 相关类型

    简介 .NET 包含多个相互关联的类型,它们表示任意内存的连续的强类型区域. 这些方法包括: System.Span<T> 用于访问连续的内存区域 得到该类型的实例: 1个T类型的数组 1 ...

随机推荐

  1. CCPC2018 桂林 G "Greatest Common Divisor"(数学)

    UPC备战省赛组队训练赛第十七场 with zyd,mxl G: Greatest Common Divisor 题目描述 There is an array of length n, contain ...

  2. H3C 子网划分方法

  3. Command failed: git -c core.longpaths=true config --get remote.origin.url

    「Unable to Connect to GitHub.com For Cloning」 Error: Command failed: git -c core.longpaths=true conf ...

  4. ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(2)之创建项目

    我们在创建项目的时候一定要遵循层次和命名的原则,同时也要有统一的规范,无论是多人项目还是单人项目,能够让人看着一目了然并赏析悦目,做一个有追求的程序员. 例如IA.WebApp是视图控制器层(表现层) ...

  5. CF Round #580(div2)题解报告

    CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...

  6. PowerShell 通过 WMI 获取系统服务

    本文告诉大家如何通过 WMI 获取系统服务 通过 Win32_Service 可以获取系统启动的服务 Get-WmiObject Win32_Service | Format-List Caption ...

  7. HDU - 3530 Subsequence (单调队列)

    Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  8. 将 using namespace 写在函数体中,以避免命名空间冲突

    将 using namespace xxx 写在函数体中时, 命名空间 xxx 中定义的资源只在该函数体中有效. 测试代码如下图所示(namespace std 只在函数 testFun2 中有效):

  9. github权限管理

    引用自:https://www.cnblogs.com/zhaoyanjun/p/5882784.html 前言: 在上一篇文章中Android github 快速实现多人协作 (http://www ...

  10. 21.模块的执行以及__name__

    执行结果: "E:\Program Files\JetBrains\PycharmProjects\python_demo\venv\Scripts\python.exe" &qu ...