过年啦,写个短点的。同时,提前给大家拜个年。

总有小伙伴们跑过来讨论关于Span和Memory的使用,眼瞅是最近关于Span的文章有点多,看飞了。

今天写这个,就是往回拉一拉。

写之前,先声明一下。这些内容是我自己使用的一些经验,并不代表这些类的全部内容就是这些,只是说,我是这么用的,而且用得很好。

1. Span

Span在我的概念中,就是一个快速的同步访问器。

就这么简单。

Span很快。在我前边关于Span的文章中分析过,可以移步【传送门】去看。而且,它与foreach一起使用也很快,主要是因为Span的GetEnumerator使用了引用返回。

你看,Span本身就被设计成了一个非常快的东西。

同时,Span是同步的。也就是说,它没有提供任何异步的方法和属性。

说到为什么Span是同步的,这倒是一个问题。我们需要从根上来找找。Span背后的连续内存块,主要来自于以下几个方面:

  • 数组的切片

  • Memory

  • 非托管指针void*

  • stackalloc

其中,第一个是堆上分配的数组的一部分。第二个是基于连续内存的。第三个非托管void*本身就是同步的。

第四个单独说一下。stackalloc提供的是在线程的堆栈上分配内存。如果Span可以使用异步,会导致一个线程可以访问另一个线程的堆栈。显然这是不安全和不合理的。所以,保持Span同步是必须的。

所以,Span就是一个性能非常好的,针对连续内存的同步访问器。

2. Memory

Memory,就是一个实际的内存块。

与Span不同,Memory可以在异步流中使用,同时,它还提供了获取同步访问器的方法Memory<T>.Span()

Memory可以有多种来源,例如:

  • 数组切片

  • MemoryMarshal的各种Create方法,例如MemoryMarshal.CreateFromPinnedArray()这样的。

第一个是最基本的用法,从数组T[]中取一个切片成为Memory。

第二个方法会复杂一些,用了一个特殊的方法来创建Memory。像上边的例子,CreateFromPinnedArray用了一个已经固定的数组。在Dotnet中,可以通过固定一个对象,来禁止GC移动对象。这在将Memory传递给非托管对象时非常有用。

总之,Memory就是一个实际的内存块。这个内存块可以被用到任何地方,并可以使用它的同步访问器Span进行访问。

3. ReadOnlyX

印象中有三种:ReadOnlySpan、ReadOnlyMemory、ReadOnlySequence。

没什么特别的,就是ReadOnly,只读啦。

前两个,ReadOnlySpan、ReadOnlyMemory,就是Span和Memory对应的只读对象。

4. ReadOnlySequence

ReadOnlySequence也不算复杂,就是一个ReadOnlyMemory元素的序列。

基于操作系统的内存管理,有时候Memory不是连续的,可能会分片段,所以就需要有个结构来表示一个Memory链/Memory列表类似的序列。这是ReadOnlySequence的由来,而它本身也是一个ReadOnlyMemory的列表。

同时,它也提供了一些属性来优化序列中包含一个元素的情况:

  • IsSingleSegment,用来快速检查是否只包含一个内存项

  • FirstSpan,该速访问ReadOnlySpan访问器的第一个内存项

因此虽然被定义为序列,但处理单个元素,例如单个Span或Memory也容易很多。

这就是今天的全部内容了。

有没有跟你用的不一样?

文章最后,再次祝大家牛年大吉,万事胜意~

喜欢就来个三连,让更多人因你而受益

Dotnet中Span, Memory和ReadOnlySequence之浅见相关推荐

  1. dotNet中,取得指定日期所在月份的最后一天

    问题: dotNet中,如何方便快速的取得指定日期所在月份的最后一天? 思路: 从指定日期所在月份下个月的1号的前一天,就是所求的内容. 实现: int GetLastDayOfMonth(DateT ...

  2. dotNet中初始化器的使用

    dotNet中初始化器的使用 2013年12月7日 13:27 有两类初始化器: 对象初始化器和集合初始化器 比如现在有一个User类: Public   class User { public in ...

  3. Dotnet中Socket网络通信

    本文介绍Socket的基本知识. TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在"无差别"的网络之上. 建立起一个TCP连接需要经过"三次握手"  ...

  4. dotnet中的counters说明(一)

    在dotnet中,常用的收集指标有: System.Runtime 计数器 Microsoft.AspNetCore.Hosting计数器 Microsoft.AspNetCore.Http.Conn ...

  5. (转帖)DotNet中的构造函数大聚会

    DotNet中的构造函数大聚会,并在此各显神通 (1)公共构造函数         共公的构造函数是最为常见的形式,允许类被使用者实例化. C#实例如下: 1class myClass 2{ 3    ...

  6. DotNet中人民币符号的输出

    DotNet中人民币符号"¥"的输出<html> <head>DotNet中人民币符号的输出</head> <body> <p ...

  7. #define barrier() __asm__ __volatile__(: : :memory) 中的memory是gcc的东西

    gcc内嵌汇编简介 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作 ...

  8. Cuda中Global memory中coalescing例程解释

    Global memory是cuda中最常见的存储类型,又叫做Device memory,位于Host主机区域上,它的生命周期是在整个Grid里面,大约具有500个cycle latency.在cud ...

  9. android 自定义span_教你自定义android中span

    在客户端开发中,我们往往需要对一个TextView的文字的部分内容进行特殊化处理,比如加粗.改变颜色.加链接.下划线等.iOS为我们提供了AttributedString,而Android则提供了Sp ...

最新文章

  1. firefox.exe not found problem (VS2005 website)
  2. 基于SSM实现在线洗衣平台
  3. 微信小程序通用开发框架小程序端包含若干基础组件
  4. SQL Sever 基本命令案例
  5. Win10 EPROCESS 断链
  6. 信息系统项目管理知识--项目配置管理
  7. C语言程序练习-L1-032 Left-pad (20分)
  8. 利用python爬虫(part6)--用Xpath匹配带来的数据合并问题
  9. android oneshot自动播放bug,移动端常见bug汇总001
  10. TYVJ P1012 火柴棒等式 Label:枚举
  11. 计算机应用理论题计算机系统,计算机应用理论题.doc
  12. 蚂蚁金服:开源增强版 SpringBoot 的研发框架!
  13. Atitit.jquery 版本新特性attilax总结
  14. usb打印机命令_自己动手不求人 日常打印机故障全知晓
  15. 简约毕业论文答辩PPT模板
  16. WireShark抓Intel网卡的802.1q包
  17. linux防病毒软件_十大Linux最佳防病毒软件-Linux防病毒软件列表!
  18. 楼梯有n个台阶,一共有多少种上楼的方法?
  19. 超详细双系统安装指南
  20. 面经分享 | 2年经验,1个月拿下阿里P6 Offer

热门文章

  1. Docker最全教程——从理论到实战(七)
  2. nowcoder OI 周赛 最后的晚餐(dinner) 解题报告
  3. linux下mysql数据库操作命令
  4. Jenkins 随笔
  5. centos打架django + mysql环境
  6. Could not load the Tomcat server configuration at \Servers\Tomcat v7.0 Server at localhost-config
  7. 世界杯,世界共同的游戏!
  8. easyui关机图标_如何在Windows 10中创建关机图标
  9. javascript基础修炼(4)——UMD规范的代码推演
  10. 《vSphere性能设计:性能密集场景下CPU、内存、存储及网络的最佳设计实践》一1.2.2 内存...